From 6c3cbf88b3ae715930883935cc7ffad479069613 Mon Sep 17 00:00:00 2001 From: "nov.lzf" Date: Fri, 26 Jul 2024 17:04:18 +0800 Subject: [PATCH 1/8] Develop uniformgraypublish (#12429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 34567 * refactor gray model * pmd checkstyle * 兼容性处理 * 灰度增量对账 * 升级内容字段编码,添加gray表 * pmd and checkstyle * merge develop fix conflict * derby create gray table * modify gray table sql * derby sql bugfix * fix test case * fix test case * fix test case --- .../api/ability/constant/AbilityKey.java | 2 + .../alibaba/nacos/api/common/Constants.java | 2 + .../ConfigChangeClusterSyncRequest.java | 10 + .../alibaba/nacos/api/model/v2/ErrorCode.java | 20 + .../nacos/api/remote/request/RequestMeta.java | 33 ++ .../nacos/api/utils/AbilityKeyTest.java | 4 +- .../server/constant/PropertiesConstant.java | 3 + .../server/controller/ConfigController.java | 43 +- .../server/controller/ConfigServletInner.java | 100 ++-- .../nacos/config/server/model/CacheItem.java | 159 +---- .../config/server/model/ConfigCacheGray.java | 117 ++++ .../config/server/model/ConfigInfo4Gray.java | 48 ++ .../server/model/ConfigInfoGrayWrapper.java | 49 ++ .../model/event/ConfigDataChangeEvent.java | 12 +- .../server/model/event/ConfigDumpEvent.java | 36 ++ .../model/event/LocalDataChangeEvent.java | 45 +- .../config/server/model/form/ConfigForm.java | 64 +- .../server/model/gray/AbstractGrayRule.java | 98 ++++ .../server/model/gray/BetaGrayRule.java | 97 +++ .../model/gray/ConfigGrayPersistInfo.java | 73 +++ .../config/server/model/gray/GrayRule.java | 76 +++ .../server/model/gray/GrayRuleManager.java | 114 ++++ .../config/server/model/gray/TagGrayRule.java | 90 +++ ...ConfigChangeBatchListenRequestHandler.java | 10 +- ...ConfigChangeClusterSyncRequestHandler.java | 44 +- .../remote/ConfigPublishRequestHandler.java | 145 ++--- .../remote/ConfigQueryRequestHandler.java | 90 +-- .../remote/RpcConfigChangeNotifier.java | 17 +- .../server/service/ConfigCacheService.java | 447 +++++--------- .../ConfigGrayModelMigrateService.java | 177 ++++++ .../service/ConfigOperationService.java | 272 +++++++-- .../server/service/ConfigSubService.java | 3 +- .../server/service/LongPollingService.java | 22 +- .../dump/DumpChangeGrayConfigWorker.java | 114 ++++ .../service/dump/DumpConfigHandler.java | 49 +- .../server/service/dump/DumpRequest.java | 48 +- .../server/service/dump/DumpService.java | 143 +---- .../service/dump/EmbeddedDumpService.java | 12 +- .../service/dump/ExternalDumpService.java | 15 +- .../service/dump/disk/ConfigDiskService.java | 66 +-- .../dump/disk/ConfigRawDiskService.java | 128 +--- .../dump/disk/ConfigRocksDbDiskService.java | 115 ++-- .../dump/processor/DumpAllBetaProcessor.java | 71 --- ...ocessor.java => DumpAllGrayProcessor.java} | 35 +- .../service/dump/processor/DumpProcessor.java | 47 +- .../service/dump/task/DumpAllGrayTask.java | 34 ++ .../server/service/dump/task/DumpTask.java | 30 +- .../ConfigInfoGrayPersistService.java | 188 ++++++ .../repository/ConfigRowMapperInjector.java | 36 ++ ...eddedConfigInfoGrayPersistServiceImpl.java | 344 +++++++++++ ...ernalConfigInfoGrayPersistServiceImpl.java | 330 +++++++++++ .../sql/EmbeddedStorageContextUtils.java | 44 ++ .../service/trace/ConfigTraceService.java | 26 +- .../nacos/config/server/utils/MD5Util.java | 3 +- .../config/server/utils/PropertyUtil.java | 15 + .../main/resources/META-INF/derby-schema.sql | 327 ++++++----- ...ba.nacos.config.server.model.gray.GrayRule | 20 + .../controller/ConfigControllerTest.java | 136 +++-- .../controller/ConfigServletInnerTest.java | 138 +++-- ...igChangeClusterSyncRequestHandlerTest.java | 70 ++- .../ConfigPublishRequestHandlerTest.java | 64 +- .../remote/ConfigQueryRequestHandlerTest.java | 79 +-- .../remote/RpcConfigChangeNotifierTest.java | 2 +- .../service/ConfigCacheServiceTest.java | 189 ++---- .../service/ConfigOperationServiceTest.java | 138 +++-- .../dump/DumpChangeConfigWorkerTest.java | 3 +- .../dump/DumpChangeGrayConfigWorkerTest.java | 115 ++++ .../service/dump/DumpProcessorTest.java | 116 +--- .../dump/DumpProcessorUserRwaDiskTest.java | 10 - .../server/service/dump/DumpServiceTest.java | 34 +- .../dump/disk/ConfigRawDiskServiceTest.java | 52 +- .../dump/processor/DumpAllProcessorTest.java | 11 +- ...dConfigInfoGrayPersistServiceImplTest.java | 363 ++++++++++++ ...lConfigInfoGrayPersistServiceImplTest.java | 551 ++++++++++++++++++ .../main/resources/META-INF/derby-schema.sql | 20 + .../src/main/resources/application.properties | 18 +- distribution/conf/derby-schema.sql | 325 ++++++----- distribution/conf/mysql-schema.sql | 32 +- .../datasource/constants/FieldConstant.java | 4 + .../datasource/constants/TableConstant.java | 2 + .../derby/ConfigInfoGrayMapperByDerby.java | 59 ++ .../mysql/ConfigInfoGrayMapperByMySql.java | 46 ++ .../mapper/ConfigInfoGrayMapper.java | 97 +++ ...baba.nacos.plugin.datasource.mapper.Mapper | 2 + .../src/test/resources/derby-schema.sql | 325 ++++++----- 85 files changed, 5410 insertions(+), 2353 deletions(-) create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/ConfigCacheGray.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo4Gray.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoGrayWrapper.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/gray/AbstractGrayRule.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/gray/BetaGrayRule.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRule.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRuleManager.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/gray/TagGrayRule.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/ConfigGrayModelMigrateService.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java delete mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllBetaProcessor.java rename config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/{DumpAllTagProcessor.java => DumpAllGrayProcessor.java} (61%) create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpAllGrayTask.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java create mode 100644 config/src/main/resources/META-INF/services/com.alibaba.nacos.config.server.model.gray.GrayRule create mode 100644 config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java create mode 100644 config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java create mode 100644 config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java create mode 100644 plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/derby/ConfigInfoGrayMapperByDerby.java create mode 100644 plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigInfoGrayMapperByMySql.java create mode 100644 plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigInfoGrayMapper.java diff --git a/api/src/main/java/com/alibaba/nacos/api/ability/constant/AbilityKey.java b/api/src/main/java/com/alibaba/nacos/api/ability/constant/AbilityKey.java index fd3baef3e8a..e7a44a148f6 100644 --- a/api/src/main/java/com/alibaba/nacos/api/ability/constant/AbilityKey.java +++ b/api/src/main/java/com/alibaba/nacos/api/ability/constant/AbilityKey.java @@ -47,6 +47,8 @@ public enum AbilityKey { */ SERVER_TEST_2("test_2", "just for junit test", AbilityMode.SERVER), + SUPPORT_NEW_GRAY_MODEL("support_new_gray_model", "support_new_gray_model", AbilityMode.SERVER), + /** * For Test temporarily. */ diff --git a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java index 0bb32558b11..5f5ac020dce 100644 --- a/api/src/main/java/com/alibaba/nacos/api/common/Constants.java +++ b/api/src/main/java/com/alibaba/nacos/api/common/Constants.java @@ -35,6 +35,8 @@ public class Constants { public static final String CLIENT_VERSION_KEY = "ClientVersion"; + public static final String CLIENT_IP = "ClientIp"; + public static final String UNKNOWN_APP = "UnknownApp"; public static final String DEFAULT_DOMAINNAME = "commonconfig.config-host.taobao.com"; diff --git a/api/src/main/java/com/alibaba/nacos/api/config/remote/request/cluster/ConfigChangeClusterSyncRequest.java b/api/src/main/java/com/alibaba/nacos/api/config/remote/request/cluster/ConfigChangeClusterSyncRequest.java index c9dab7288f6..a2f188679cc 100644 --- a/api/src/main/java/com/alibaba/nacos/api/config/remote/request/cluster/ConfigChangeClusterSyncRequest.java +++ b/api/src/main/java/com/alibaba/nacos/api/config/remote/request/cluster/ConfigChangeClusterSyncRequest.java @@ -34,6 +34,8 @@ public class ConfigChangeClusterSyncRequest extends AbstractConfigRequest { boolean isBatch; + String grayName; + public boolean isBeta() { return isBeta; } @@ -68,6 +70,14 @@ public void setTag(String tag) { this.tag = tag; } + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + /** * Getter method for property lastModified. * diff --git a/api/src/main/java/com/alibaba/nacos/api/model/v2/ErrorCode.java b/api/src/main/java/com/alibaba/nacos/api/model/v2/ErrorCode.java index 53b4c35735f..fd219e430f6 100644 --- a/api/src/main/java/com/alibaba/nacos/api/model/v2/ErrorCode.java +++ b/api/src/main/java/com/alibaba/nacos/api/model/v2/ErrorCode.java @@ -90,6 +90,26 @@ public enum ErrorCode { */ PARAMETER_MISMATCH(20009, "parameter mismatch"), + /** + * config gray request error. + */ + CONFIG_GRAY_OVER_MAX_VERSION_COUNT(20010, "config gray version version over max count"), + + /** + * config gray tag v2 rule format invalid. + */ + CONFIG_GRAY_RULE_FORMAT_INVALID(20011, "config gray rule format invalid"), + + /** + * config gray tag v2 rule version invalid. + */ + CONFIG_GRAY_VERSION_INVALID(20012, "config gray rule version invalid"), + + /** + * config gray request error. + */ + CONFIG_GRAY_NAME_UNRECOGNIZED_ERROR(20013, "config gray name not recognized"), + /** * service name error. */ diff --git a/api/src/main/java/com/alibaba/nacos/api/remote/request/RequestMeta.java b/api/src/main/java/com/alibaba/nacos/api/remote/request/RequestMeta.java index c633f893484..478a8780059 100644 --- a/api/src/main/java/com/alibaba/nacos/api/remote/request/RequestMeta.java +++ b/api/src/main/java/com/alibaba/nacos/api/remote/request/RequestMeta.java @@ -18,9 +18,11 @@ import com.alibaba.nacos.api.ability.constant.AbilityKey; import com.alibaba.nacos.api.ability.constant.AbilityStatus; +import com.alibaba.nacos.api.common.Constants; import java.util.HashMap; import java.util.Map; +import java.util.Objects; /** * RequestMeta info. @@ -38,6 +40,8 @@ public class RequestMeta { private Map labels = new HashMap<>(); + private Map appLabels = new HashMap<>(); + private Map abilityTable; public AbilityStatus getConnectionAbility(AbilityKey abilityKey) { @@ -90,6 +94,35 @@ public Map getLabels() { */ public void setLabels(Map labels) { this.labels = labels; + extractAppLabels(); + } + + private void extractAppLabels() { + HashMap applabelsMap = new HashMap(8) { + { + put(Constants.APPNAME, labels.get(Constants.APPNAME)); + put(Constants.CONFIG_VERSION, clientVersion); + put(Constants.CLIENT_IP, clientIp); + } + }; + labels.entrySet().stream().filter(Objects::nonNull).filter(e -> e.getKey().startsWith(Constants.APP_CONN_PREFIX) + && e.getKey().length() > Constants.APP_CONN_PREFIX.length() && !e.getValue().trim().isEmpty()) + .forEach(entry -> { + applabelsMap.putIfAbsent(entry.getKey().substring(Constants.APP_CONN_PREFIX.length()), + entry.getValue()); + }); + this.appLabels = applabelsMap; + } + + /** + * get labels map with filter of starting with prefix #{@link Constants#APP_CONN_PREFIX} and return a new map trim + * the prefix #{@link Constants#APP_CONN_PREFIX}. + * + * @return map of labels. + * @date 2024/2/29 + */ + public Map getAppLabels() { + return appLabels; } /** diff --git a/api/src/test/java/com/alibaba/nacos/api/utils/AbilityKeyTest.java b/api/src/test/java/com/alibaba/nacos/api/utils/AbilityKeyTest.java index 0812ce18723..1776287ce98 100644 --- a/api/src/test/java/com/alibaba/nacos/api/utils/AbilityKeyTest.java +++ b/api/src/test/java/com/alibaba/nacos/api/utils/AbilityKeyTest.java @@ -97,7 +97,7 @@ void testMapEnum() { @Test void testGetAllValues() { Collection actual = AbilityKey.getAllValues(AbilityMode.SERVER); - assertEquals(3, actual.size()); + assertEquals(4, actual.size()); actual = AbilityKey.getAllValues(AbilityMode.SDK_CLIENT); assertEquals(1, actual.size()); actual = AbilityKey.getAllValues(AbilityMode.CLUSTER_CLIENT); @@ -107,7 +107,7 @@ void testGetAllValues() { @Test void testGetAllNames() { Collection actual = AbilityKey.getAllNames(AbilityMode.SERVER); - assertEquals(3, actual.size()); + assertEquals(4, actual.size()); actual = AbilityKey.getAllNames(AbilityMode.SDK_CLIENT); assertEquals(1, actual.size()); actual = AbilityKey.getAllNames(AbilityMode.CLUSTER_CLIENT); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/constant/PropertiesConstant.java b/config/src/main/java/com/alibaba/nacos/config/server/constant/PropertiesConstant.java index f448567daa9..eeea1fa8d4f 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/constant/PropertiesConstant.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/constant/PropertiesConstant.java @@ -63,5 +63,8 @@ public class PropertiesConstant { public static final String DUMP_CHANGE_WORKER_INTERVAL = "dumpChangeWorkerInterval"; + public static final String GRAY_CAPATIBEL_MODEL = "nacos.config.gray.compatible.model"; + + } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java index cbaffe84989..8165b1b0dd2 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java @@ -31,11 +31,15 @@ import com.alibaba.nacos.config.server.model.ConfigAllInfo; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfo4Beta; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigMetadata; import com.alibaba.nacos.config.server.model.GroupkeyListenserStatus; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; import com.alibaba.nacos.config.server.paramcheck.ConfigBlurSearchHttpParamExtractor; import com.alibaba.nacos.config.server.paramcheck.ConfigDefaultHttpParamExtractor; import com.alibaba.nacos.config.server.paramcheck.ConfigListenerHttpParamExtractor; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.core.paramcheck.ExtractorManager; import com.alibaba.nacos.persistence.model.Page; import com.alibaba.nacos.config.server.model.SameConfigPolicy; @@ -66,6 +70,7 @@ import com.alibaba.nacos.sys.utils.InetUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -121,6 +126,8 @@ public class ConfigController { private ConfigInfoBetaPersistService configInfoBetaPersistService; + private ConfigInfoGrayPersistService configInfoGrayPersistService; + private NamespacePersistService namespacePersistService; private final ConfigOperationService configOperationService; @@ -129,14 +136,15 @@ public class ConfigController { public ConfigController(ConfigServletInner inner, ConfigOperationService configOperationService, ConfigSubService configSubService, ConfigInfoPersistService configInfoPersistService, - NamespacePersistService namespacePersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService) { + NamespacePersistService namespacePersistService, ConfigInfoBetaPersistService configInfoBetaPersistService, + ConfigInfoGrayPersistService configInfoGrayPersistService) { this.inner = inner; this.configOperationService = configOperationService; this.configSubService = configSubService; this.configInfoPersistService = configInfoPersistService; this.namespacePersistService = namespacePersistService; this.configInfoBetaPersistService = configInfoBetaPersistService; + this.configInfoGrayPersistService = configInfoGrayPersistService; } /** @@ -194,7 +202,6 @@ public Boolean publishConfig(HttpServletRequest request, HttpServletResponse res configForm.setEffect(effect); configForm.setType(type); configForm.setSchema(schema); - if (StringUtils.isBlank(srcUser)) { configForm.setSrcUser(RequestUtil.getSrcUserName(request)); } @@ -453,7 +460,8 @@ public RestResult stopBeta(HttpServletRequest httpServletRequest, String remoteIp = getRemoteIp(httpServletRequest); String requestIpApp = RequestUtil.getAppName(httpServletRequest); try { - configInfoBetaPersistService.removeConfigInfo4Beta(dataId, group, tenant); + configInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, "beta", remoteIp, + RequestUtil.getSrcUserName(httpServletRequest)); } catch (Throwable e) { LOGGER.error("remove beta data error", e); return RestResultUtils.failed(500, false, "remove beta data error"); @@ -461,7 +469,13 @@ public RestResult stopBeta(HttpServletRequest httpServletRequest, ConfigTraceService.logPersistenceEvent(dataId, group, tenant, requestIpApp, System.currentTimeMillis(), remoteIp, ConfigTraceService.PERSISTENCE_EVENT_BETA, ConfigTraceService.PERSISTENCE_TYPE_REMOVE, null); ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(true, dataId, group, tenant, System.currentTimeMillis())); + new ConfigDataChangeEvent(dataId, group, tenant, null, "beta", System.currentTimeMillis())); + + if (PropertyUtil.isGrayCompatibleModel()) { + configInfoBetaPersistService.removeConfigInfo4Beta(dataId, group, tenant); + ConfigChangePublisher.notifyConfigChange( + new ConfigDataChangeEvent(true, dataId, group, tenant, System.currentTimeMillis())); + } return RestResultUtils.success("stop beta ok", true); } @@ -480,14 +494,21 @@ public RestResult queryBeta(@RequestParam(value = "dataId") Str @RequestParam(value = "group") String group, @RequestParam(value = "tenant", required = false, defaultValue = StringUtils.EMPTY) String tenant) { try { - ConfigInfo4Beta ci = configInfoBetaPersistService.findConfigInfo4Beta(dataId, group, tenant); - if (Objects.nonNull(ci)) { - String encryptedDataKey = ci.getEncryptedDataKey(); - Pair pair = EncryptionHandler.decryptHandler(dataId, encryptedDataKey, ci.getContent()); - ci.setContent(pair.getSecond()); + ConfigInfo4Beta configInfo4Beta = null; + ConfigInfoGrayWrapper beta4Gray = configInfoGrayPersistService.findConfigInfo4Gray(dataId, group, tenant, + "beta"); + if (Objects.nonNull(beta4Gray)) { + String encryptedDataKey = beta4Gray.getEncryptedDataKey(); + Pair pair = EncryptionHandler.decryptHandler(dataId, encryptedDataKey, + beta4Gray.getContent()); + beta4Gray.setContent(pair.getSecond()); + configInfo4Beta = new ConfigInfo4Beta(); + BeanUtils.copyProperties(beta4Gray, configInfo4Beta); + configInfo4Beta.setBetaIps( + GrayRuleManager.deserializeConfigGrayPersistInfo(beta4Gray.getGrayRule()).getExpr()); } - return RestResultUtils.success("query beta ok", ci); + return RestResultUtils.success("query beta ok", configInfo4Beta); } catch (Throwable e) { LOGGER.error("query beta data error", e); return RestResultUtils.failed("query beta data error"); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java index 4accddd06b4..f5c94e66265 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigServletInner.java @@ -26,7 +26,9 @@ import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.enums.FileTypeEnum; import com.alibaba.nacos.config.server.model.CacheItem; -import com.alibaba.nacos.config.server.model.ConfigCache; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.LongPollingService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; @@ -49,6 +51,7 @@ import java.io.PrintWriter; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -149,9 +152,6 @@ public String doGetConfig(HttpServletRequest request, HttpServletResponse respon if (lockResult > 0 && cacheItem != null) { try { long lastModified; - boolean isBeta = - cacheItem.isBeta() && cacheItem.getConfigCacheBeta() != null && cacheItem.getIps4Beta() != null - && cacheItem.getIps4Beta().contains(clientIp); final String configType = (null != cacheItem.getType()) ? cacheItem.getType() : FileTypeEnum.TEXT.getFileType(); @@ -160,46 +160,62 @@ public String doGetConfig(HttpServletRequest request, HttpServletResponse respon String contentTypeHeader = fileTypeEnum.getContentType(); response.setHeader(HttpHeaderConsts.CONTENT_TYPE, isV2 ? MediaType.APPLICATION_JSON : contentTypeHeader); + + ConfigCacheGray matchedGray = null; + Map appLabels = new HashMap(4); + appLabels.put(BetaGrayRule.CLIENT_IP_LABEL, clientIp); + boolean specificTag = StringUtils.isNotBlank(tag); + + if (specificTag) { + appLabels.put(TagGrayRule.VIP_SERVER_TAG_LABEL, tag); + } else if (StringUtils.isNotBlank(autoTag)) { + appLabels.put(TagGrayRule.VIP_SERVER_TAG_LABEL, autoTag); + } + + if (cacheItem.getSortConfigGrays() != null && !cacheItem.getSortConfigGrays().isEmpty()) { + for (ConfigCacheGray configCacheGray : cacheItem.getSortConfigGrays()) { + if (configCacheGray.match(appLabels)) { + matchedGray = configCacheGray; + break; + } + } + } + String pullEvent; String content; String md5; String encryptedDataKey; - if (isBeta) { - ConfigCache configCacheBeta = cacheItem.getConfigCacheBeta(); - pullEvent = ConfigTraceService.PULL_EVENT_BETA; - md5 = configCacheBeta.getMd5(acceptCharset); - lastModified = configCacheBeta.getLastModifiedTs(); - encryptedDataKey = configCacheBeta.getEncryptedDataKey(); - content = ConfigDiskServiceFactory.getInstance().getBetaContent(dataId, group, tenant); - response.setHeader("isBeta", "true"); - } else { - if (StringUtils.isBlank(tag)) { - if (isUseTag(cacheItem, autoTag)) { - - ConfigCache configCacheTag = cacheItem.getConfigCacheTags().get(autoTag); - md5 = configCacheTag.getMd5(acceptCharset); - lastModified = configCacheTag.getLastModifiedTs(); - encryptedDataKey = configCacheTag.getEncryptedDataKey(); - content = ConfigDiskServiceFactory.getInstance() - .getTagContent(dataId, group, tenant, autoTag); - pullEvent = ConfigTraceService.PULL_EVENT_TAG + "-" + autoTag; - response.setHeader(com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG, - URLEncoder.encode(autoTag, StandardCharsets.UTF_8.displayName())); - } else { - pullEvent = ConfigTraceService.PULL_EVENT; - md5 = cacheItem.getConfigCache().getMd5(acceptCharset); - lastModified = cacheItem.getConfigCache().getLastModifiedTs(); - encryptedDataKey = cacheItem.getConfigCache().getEncryptedDataKey(); - content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); - } - } else { - md5 = cacheItem.getTagMd5(tag, acceptCharset); - lastModified = cacheItem.getTagLastModified(tag); - encryptedDataKey = cacheItem.getTagEncryptedDataKey(tag); - - content = ConfigDiskServiceFactory.getInstance().getTagContent(dataId, group, tenant, tag); - pullEvent = ConfigTraceService.PULL_EVENT_TAG + "-" + tag; + + if (matchedGray != null) { + md5 = matchedGray.getMd5(acceptCharset); + lastModified = matchedGray.getLastModifiedTs(); + encryptedDataKey = matchedGray.getEncryptedDataKey(); + content = ConfigDiskServiceFactory.getInstance() + .getGrayContent(dataId, group, tenant, matchedGray.getGrayName()); + pullEvent = ConfigTraceService.PULL_EVENT + "-" + matchedGray.getGrayName(); + if (BetaGrayRule.TYPE_BETA.equals(matchedGray.getGrayName())) { + response.setHeader("isBeta", "true"); + } + if (TagGrayRule.TYPE_TAG.equals(matchedGray.getGrayRule().getType())) { + response.setHeader(com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG, + URLEncoder.encode(matchedGray.getGrayRule().getRawGrayRuleExp(), + StandardCharsets.UTF_8.displayName())); } + } else if (specificTag) { + //specific tag is not found + md5 = null; + lastModified = 0L; + encryptedDataKey = null; + content = null; + pullEvent = ConfigTraceService.PULL_EVENT + "-" + TagGrayRule.TYPE_TAG + "-" + tag; + response.setHeader(com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG, + URLEncoder.encode(tag, StandardCharsets.UTF_8.displayName())); + } else { + md5 = cacheItem.getConfigCache().getMd5(acceptCharset); + lastModified = cacheItem.getConfigCache().getLastModifiedTs(); + encryptedDataKey = cacheItem.getConfigCache().getEncryptedDataKey(); + content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); + pullEvent = ConfigTraceService.PULL_EVENT; } if (content == null) { @@ -276,10 +292,4 @@ private String get409Result(HttpServletResponse response, boolean isV2) throws I } return HttpServletResponse.SC_CONFLICT + ""; } - - private static boolean isUseTag(CacheItem cacheItem, String tag) { - return cacheItem != null && cacheItem.getConfigCacheTags() != null && cacheItem.getConfigCacheTags() - .containsKey(tag); - } - } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java b/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java index 3721a8b34ca..c63ad72d224 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/CacheItem.java @@ -20,6 +20,7 @@ import com.alibaba.nacos.core.utils.StringPool; import java.util.ArrayList; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,27 +39,11 @@ public class CacheItem { ConfigCache configCache = new ConfigCache(); /** - * Use for beta. + * Use for tagv2. */ - public volatile boolean isBeta = false; + private volatile Map configCacheGray = null; - public volatile List ips4Beta; - - ConfigCache configCacheBeta = null; - - /** - * Use for batch. - */ - public volatile boolean isBatch = false; - - public volatile int delimiter = 0; - - ConfigCache configCacheBatch = null; - - /** - * Use for tag. - */ - private volatile Map configCacheTags = null; + List sortedConfigCacheGrayList = null; private final SimpleReadWriteLock rwLock = new SimpleReadWriteLock(); @@ -75,31 +60,6 @@ public ConfigCache getConfigCache() { return configCache; } - public boolean isBeta() { - return isBeta; - } - - public void setBeta(boolean isBeta) { - this.isBeta = isBeta; - } - - /** - * remove beta. - */ - public void removeBeta() { - this.isBeta = false; - this.ips4Beta = null; - configCacheBeta = null; - } - - public List getIps4Beta() { - return ips4Beta; - } - - public void setIps4Beta(List ips4Beta) { - this.ips4Beta = ips4Beta; - } - public SimpleReadWriteLock getRwLock() { return rwLock; } @@ -117,111 +77,50 @@ public String getGroupKey() { } /** - * init beta cache if empty. + * init config gray if empty. */ - public void initBetaCacheIfEmpty() { - if (this.configCacheBeta == null) { - this.configCacheBeta = new ConfigCache(); - } - if (this.ips4Beta == null) { - this.ips4Beta = new ArrayList<>(); + public void initConfigGrayIfEmpty() { + if (this.configCacheGray == null) { + this.configCacheGray = new HashMap<>(4); } } /** - * get config cache beta. + * init config gray if empty. * - * @return - */ - public ConfigCache getConfigCacheBeta() { - return configCacheBeta; - } - - /** - * init batch cache if empty. + * @param grayName gray name. */ - public void initBatchCacheIfEmpty() { - if (this.configCacheBatch == null) { - this.configCacheBatch = new ConfigCache(); + public void initConfigGrayIfEmpty(String grayName) { + initConfigGrayIfEmpty(); + if (!this.configCacheGray.containsKey(grayName)) { + this.configCacheGray.put(grayName, new ConfigCacheGray(grayName)); } } - public ConfigCache getConfigCacheBatch() { - return configCacheBatch; + public List getSortConfigGrays() { + return sortedConfigCacheGrayList; } /** - * remove batch. + * sort config gray. */ - public void removeBatch() { - this.configCacheBatch = null; - this.isBatch = false; - } - - /** - * init config tags if empty. - */ - public void initConfigTagsIfEmpty() { - if (this.getConfigCacheTags() == null) { - this.configCacheTags = new HashMap<>(16); - } - } - - /** - * init config tag if empty. - * - * @param tag tag. - */ - public void initConfigTagsIfEmpty(String tag) { - initConfigTagsIfEmpty(); - if (!this.configCacheTags.containsKey(tag)) { - this.configCacheTags.put(tag, new ConfigCache()); - } - } - - public void clearConfigTags() { - this.configCacheTags = null; - } - - public Map getConfigCacheTags() { - return configCacheTags; - } - - public boolean isBatch() { - return isBatch; - } - - public void setBatch(boolean batch) { - isBatch = batch; - } - - public int getDelimiter() { - return delimiter; - } - - public void setDelimiter(int delimiter) { - this.delimiter = delimiter; - } - - public long getTagLastModified(String tag) { - if (configCacheTags == null || !configCacheTags.containsKey(tag)) { - return -1L; + public void sortConfigGray() { + if (configCacheGray == null || configCacheGray.isEmpty()) { + sortedConfigCacheGrayList = null; + return; } - return configCacheTags.get(tag).getLastModifiedTs(); + sortedConfigCacheGrayList = configCacheGray.entrySet().stream() + .sorted(Comparator.comparingInt(o -> o.getValue().getPriority())) + .collect(ArrayList::new, (list, item) -> list.add(item.getValue()), ArrayList::addAll); } - public String getTagEncryptedDataKey(String tag) { - if (configCacheTags == null || !configCacheTags.containsKey(tag)) { - return null; - } - return configCacheTags.get(tag).getEncryptedDataKey(); + public Map getConfigCacheGray() { + return configCacheGray; } - public String getTagMd5(String tag, String encode) { - if (configCacheTags == null || !configCacheTags.containsKey(tag)) { - return null; - } - return configCacheTags.get(tag).getMd5(encode); + public void clearConfigGrays() { + this.configCacheGray = null; + this.sortedConfigCacheGrayList = null; } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigCacheGray.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigCacheGray.java new file mode 100644 index 00000000000..f3c8ccfd700 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigCacheGray.java @@ -0,0 +1,117 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model; + +import com.alibaba.nacos.config.server.model.gray.GrayRule; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; + +import java.io.Serializable; +import java.util.Map; + +/** + * extensible config cache. + * + * @author rong + */ +public class ConfigCacheGray extends ConfigCache implements Serializable { + + private String grayName; + + private GrayRule grayRule; + + /** + * clear cache. + */ + @Override + public void clear() { + super.clear(); + } + + public ConfigCacheGray(String grayName) { + this.grayName = grayName; + } + + public GrayRule getGrayRule() { + return grayRule; + } + + public ConfigCacheGray(String md5Gbk, String md5Utf8, long lastModifiedTs, String grayRule) + throws RuntimeException { + super(md5Gbk, md5Utf8, lastModifiedTs); + this.grayRule = GrayRuleManager.constructGrayRule(GrayRuleManager.deserializeConfigGrayPersistInfo(grayRule)); + if (this.grayRule == null || !this.grayRule.isValid()) { + throw new RuntimeException("raw gray rule is invalid"); + } + } + + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + + /** + * get raw gray rule from db. + * + * @return raw gray rule from db. + * @date 2024/3/14 + */ + public String getRawGrayRule() { + return grayRule.getRawGrayRuleExp(); + } + + /** + * reset gray rule. + * + * @param grayRule raw gray rule from db. + * @throws RuntimeException if gray rule is invalid. + * @date 2024/3/14 + */ + public void resetGrayRule(String grayRule) throws RuntimeException { + this.grayRule = GrayRuleManager.constructGrayRule(GrayRuleManager.deserializeConfigGrayPersistInfo(grayRule)); + if (this.grayRule == null || !this.grayRule.isValid()) { + throw new RuntimeException("raw gray rule is invalid"); + } + } + + /** + * judge whether match gray rule. + * + * @param tags conn tags. + * @return true if match, false otherwise. + * @date 2024/3/14 + */ + public boolean match(Map tags) { + return grayRule.match(tags); + } + + public int getPriority() { + return grayRule.getPriority(); + } + + /** + * if gray rule is valid. + * + * @return true if valid, false otherwise. + * @date 2024/3/14 + */ + public boolean isValid() { + return grayRule != null && grayRule.isValid(); + } +} \ No newline at end of file diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo4Gray.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo4Gray.java new file mode 100644 index 00000000000..a3a41c7ef1d --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfo4Gray.java @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model; + +/** + * configInfo4Gray. + * + * @author rong + */ +public class ConfigInfo4Gray extends ConfigInfo { + + private String grayName; + + private String grayRule; + + public ConfigInfo4Gray() { + } + + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + + public String getGrayRule() { + return grayRule; + } + + public void setGrayRule(String grayRule) { + this.grayRule = grayRule; + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoGrayWrapper.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoGrayWrapper.java new file mode 100644 index 00000000000..1b8c1cd9c78 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoGrayWrapper.java @@ -0,0 +1,49 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model; + +/** + * ConfigInfoGrayWrapper. + * @author rong + */ +public class ConfigInfoGrayWrapper extends ConfigInfo4Gray { + + private static final long serialVersionUID = 4511997591465712505L; + + private long lastModified; + + public ConfigInfoGrayWrapper() { + } + + public long getLastModified() { + return lastModified; + } + + public void setLastModified(long lastModified) { + this.lastModified = lastModified; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } +} \ No newline at end of file diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java index 7ee4cb192fe..4c5e060e14d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDataChangeEvent.java @@ -38,6 +38,8 @@ public class ConfigDataChangeEvent extends Event { public final String tag; + public final String grayName; + public final long lastModifiedTs; public ConfigDataChangeEvent(String dataId, String group, long gmtModified) { @@ -55,6 +57,7 @@ public ConfigDataChangeEvent(boolean isBeta, String dataId, String group, String this.tag = null; this.isBatch = false; this.lastModifiedTs = gmtModified; + this.grayName = null; } public ConfigDataChangeEvent(boolean isBeta, String dataId, String group, long gmtModified) { @@ -72,10 +75,12 @@ public ConfigDataChangeEvent(boolean isBeta, String dataId, String group, String this.tenant = tenant; this.tag = tag; this.isBatch = false; + this.grayName = null; this.lastModifiedTs = gmtModified; } - public ConfigDataChangeEvent(String dataId, String group, String tenant, boolean isBatch, long gmtModified) { + public ConfigDataChangeEvent(String dataId, String group, String tenant, String tag, String grayName, + long gmtModified) { if (null == dataId || null == group) { throw new IllegalArgumentException(); } @@ -83,8 +88,9 @@ public ConfigDataChangeEvent(String dataId, String group, String tenant, boolean this.dataId = dataId; this.group = group; this.tenant = tenant; - this.tag = null; - this.isBatch = isBatch; + this.tag = tag; + this.isBatch = false; + this.grayName = grayName; this.lastModifiedTs = gmtModified; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java index c1ec3b358e3..f9e408fa43f 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/ConfigDumpEvent.java @@ -45,6 +45,10 @@ public class ConfigDumpEvent extends Event { private String tag; + private String grayName; + + private String grayRule; + private String content; private String betaIps; @@ -167,6 +171,22 @@ public void setEncryptedDataKey(String encryptedDataKey) { this.encryptedDataKey = encryptedDataKey; } + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + + public String getGrayRule() { + return grayRule; + } + + public void setGrayRule(String grayRule) { + this.grayRule = grayRule; + } + public static ConfigDumpEventBuilder builder() { return new ConfigDumpEventBuilder(); } @@ -189,6 +209,10 @@ public static final class ConfigDumpEventBuilder { private String tag; + private String grayName; + + private String grayRule; + private String encryptedDataKey; private String content; @@ -239,6 +263,16 @@ public ConfigDumpEventBuilder tag(String tag) { return this; } + public ConfigDumpEventBuilder grayName(String grayName) { + this.grayName = grayName; + return this; + } + + public ConfigDumpEventBuilder grayRule(String grayRule) { + this.grayRule = grayRule; + return this; + } + public ConfigDumpEventBuilder content(String content) { this.content = content; return this; @@ -294,6 +328,8 @@ public ConfigDumpEvent build() { configDumpEvent.setBatch(isBatch); configDumpEvent.setDelimiter(delimiter); configDumpEvent.setLastModifiedTs(lastModifiedTs); + configDumpEvent.setGrayName(grayName); + configDumpEvent.setGrayRule(grayRule); configDumpEvent.isBeta = this.isBeta; return configDumpEvent; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java b/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java index 39ac52a71ec..cd2b935291a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/event/LocalDataChangeEvent.java @@ -18,8 +18,6 @@ import com.alibaba.nacos.common.notify.Event; -import java.util.List; - /** * LocalDataChangeEvent. * @@ -29,49 +27,8 @@ public class LocalDataChangeEvent extends Event { public final String groupKey; - public final boolean isBeta; - - public final List betaIps; - - public final String tag; - - public final boolean isBatch; - - public final int delimiter; - public LocalDataChangeEvent(String groupKey) { this.groupKey = groupKey; - this.isBeta = false; - this.betaIps = null; - this.tag = null; - this.isBatch = false; - this.delimiter = 0; - } - - public LocalDataChangeEvent(String groupKey, boolean isBeta, List betaIps) { - this.groupKey = groupKey; - this.isBeta = isBeta; - this.betaIps = betaIps; - this.tag = null; - this.isBatch = false; - this.delimiter = 0; - } - - public LocalDataChangeEvent(String groupKey, String tag) { - this.groupKey = groupKey; - this.isBeta = false; - this.betaIps = null; - this.tag = tag; - this.isBatch = false; - this.delimiter = 0; - } - - public LocalDataChangeEvent(String groupKey, boolean isBatch, int delimiter) { - this.groupKey = groupKey; - this.isBeta = false; - this.betaIps = null; - this.tag = null; - this.isBatch = isBatch; - this.delimiter = delimiter; } + } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/form/ConfigForm.java b/config/src/main/java/com/alibaba/nacos/config/server/model/form/ConfigForm.java index cf58f4a6d89..39e828ad19e 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/form/ConfigForm.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/form/ConfigForm.java @@ -50,6 +50,16 @@ public class ConfigForm implements Serializable { private String configTags; + private String encryptedDataKey; + + private String grayName; + + private String grayRuleExp; + + private String grayVersion; + + private int grayPriority; + private String desc; private String use; @@ -60,14 +70,11 @@ public class ConfigForm implements Serializable { private String schema; - private String encryptedDataKey; - public ConfigForm() { } public ConfigForm(String dataId, String group, String namespaceId, String content, String tag, String appName, - String srcUser, String configTags, String desc, String use, String effect, String type, String schema, - String encryptedDataKey) { + String srcUser, String configTags, String desc, String use, String effect, String type, String schema) { this.dataId = dataId; this.group = group; this.namespaceId = namespaceId; @@ -81,7 +88,6 @@ public ConfigForm(String dataId, String group, String namespaceId, String conten this.effect = effect; this.type = type; this.schema = schema; - this.encryptedDataKey = encryptedDataKey; } public String getDataId() { @@ -196,6 +202,38 @@ public void setEncryptedDataKey(String encryptedDataKey) { this.encryptedDataKey = encryptedDataKey; } + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + + public String getGrayRuleExp() { + return grayRuleExp; + } + + public void setGrayRuleExp(String grayRuleExp) { + this.grayRuleExp = grayRuleExp; + } + + public String getGrayVersion() { + return grayVersion; + } + + public void setGrayVersion(String grayVersion) { + this.grayVersion = grayVersion; + } + + public int getGrayPriority() { + return grayPriority; + } + + public void setGrayPriority(int grayPriority) { + this.grayPriority = grayPriority; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -208,16 +246,18 @@ public boolean equals(Object o) { return dataId.equals(configForm.dataId) && group.equals(configForm.group) && Objects.equals(namespaceId, configForm.namespaceId) && content.equals(configForm.content) && Objects.equals(tag, configForm.tag) && Objects .equals(appName, configForm.appName) && Objects.equals(srcUser, configForm.srcUser) && Objects - .equals(configTags, configForm.configTags) && Objects.equals(desc, configForm.desc) && Objects.equals( - use, configForm.use) && Objects.equals(effect, configForm.effect) && Objects.equals(type, - configForm.type) && Objects.equals(schema, configForm.schema) && Objects.equals(encryptedDataKey, - configForm.encryptedDataKey); + .equals(configTags, configForm.configTags) && Objects.equals(desc, configForm.desc) && Objects + .equals(use, configForm.use) && Objects.equals(effect, configForm.effect) && Objects + .equals(type, configForm.type) && Objects.equals(schema, configForm.schema) && Objects + .equals(encryptedDataKey, configForm.encryptedDataKey) && Objects + .equals(grayName, configForm.grayName) && Objects.equals(grayVersion, configForm.grayVersion) && Objects + .equals(grayPriority, configForm.grayPriority); } @Override public int hashCode() { return Objects.hash(dataId, group, namespaceId, content, tag, appName, srcUser, configTags, desc, use, effect, type, - schema, encryptedDataKey); + schema, encryptedDataKey, grayName, grayVersion, grayPriority); } @Override @@ -226,7 +266,9 @@ public String toString() { + ", content='" + content + '\'' + ", tag='" + tag + '\'' + ", appName='" + appName + '\'' + ", srcUser='" + srcUser + '\'' + ", configTags='" + configTags + '\'' + ", desc='" + desc + '\'' + ", use='" + use + '\'' + ", effect='" + effect + '\'' + ", type='" + type + '\'' + ", schema='" - + schema + '\'' + ", encryptedDataKey='" + encryptedDataKey + '\'' + '}'; + + schema + '\'' + "encryptedDataKey" + encryptedDataKey + '\'' + ", grayName='" + grayName + '\'' + + ", grayRule='" + grayRuleExp + '\'' + ", grayVersion='" + grayVersion + '\'' + ", grayPriority=" + + grayPriority + '}'; } /** diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/AbstractGrayRule.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/AbstractGrayRule.java new file mode 100644 index 00000000000..641ea74fab0 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/AbstractGrayRule.java @@ -0,0 +1,98 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model.gray; + +import com.alibaba.nacos.api.exception.NacosException; + +import java.util.Map; + +/** + * Gray rule. type with version determined parse logic. + * + * @author shiyiyue + */ +public abstract class AbstractGrayRule implements GrayRule { + + protected String rawGrayRuleExp; + + protected int priority; + + protected volatile boolean valid = true; + + public AbstractGrayRule() { + } + + public AbstractGrayRule(String rawGrayRuleExp, int priority) { + try { + parse(rawGrayRuleExp); + this.priority = priority; + } catch (NacosException e) { + valid = false; + } + this.rawGrayRuleExp = rawGrayRuleExp; + } + + /** + * parse gray rule. + * + * @param rawGrayRule raw gray rule. + * @throws NacosException if parse failed. + * @date 2024/3/14 + */ + protected abstract void parse(String rawGrayRule) throws NacosException; + + /** + * match gray rule. + * + * @param labels conn labels. + * @return true if match. + * @date 2024/3/14 + */ + public abstract boolean match(Map labels); + + public boolean isValid() { + return valid; + } + + /** + * get type. + * + * @return gray rule type. + * @date 2024/3/14 + */ + public abstract String getType(); + + /** + * get version. + * + * @return gray rule version. + * @date 2024/3/14 + */ + public abstract String getVersion(); + + public String getRawGrayRuleExp() { + return rawGrayRuleExp; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/BetaGrayRule.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/BetaGrayRule.java new file mode 100644 index 00000000000..0394f6d6b88 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/BetaGrayRule.java @@ -0,0 +1,97 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model.gray; + +import com.alibaba.nacos.api.exception.NacosException; + +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * beta gray rule for beta ips. + * @author shiyiyue1102 + */ +public class BetaGrayRule extends AbstractGrayRule { + + Set betaIps; + + public static final String CLIENT_IP_LABEL = "ClientIp"; + + public static final String TYPE_BETA = "beta"; + + public static final String VERSION = "1.0.0"; + + public static final int PROPRITY = -1000; + + public BetaGrayRule() { + super(); + } + + public BetaGrayRule(String rawGrayRuleExp, int priority) { + super(rawGrayRuleExp, priority); + } + + /** + * parse beta gray rule. + * @param rawGrayRule raw gray rule. + * @throws NacosException exception. + */ + @Override + protected void parse(String rawGrayRule) throws NacosException { + Set betaIps = new HashSet<>(); + String[] ips = rawGrayRule.split(","); + for (String ip : ips) { + betaIps.add(ip); + } + this.betaIps = betaIps; + } + + @Override + + public boolean match(Map labels) { + return labels.containsKey(CLIENT_IP_LABEL) && betaIps.contains(labels.get(CLIENT_IP_LABEL)); + } + + @Override + public String getType() { + return TYPE_BETA; + } + + @Override + public String getVersion() { + return VERSION; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + BetaGrayRule that = (BetaGrayRule) o; + return Objects.equals(betaIps, that.betaIps); + } + + @Override + public int hashCode() { + return Objects.hash(betaIps); + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java new file mode 100644 index 00000000000..c8539ab619f --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java @@ -0,0 +1,73 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model.gray; + +/** + * description. + * + * @author rong + * @date 2024-03-14 10:57 + */ +public class ConfigGrayPersistInfo { + + private String type; + + private String version; + + private String expr; + + private int priority; + + public ConfigGrayPersistInfo(String type, String version, String expr, int priority) { + this.type = type; + this.version = version; + this.expr = expr; + this.priority = priority; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getExpr() { + return expr; + } + + public void setExpr(String expr) { + this.expr = expr; + } + + public int getPriority() { + return priority; + } + + public void setPriority(int priority) { + this.priority = priority; + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRule.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRule.java new file mode 100644 index 00000000000..5fa2e48007f --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRule.java @@ -0,0 +1,76 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model.gray; + +import java.util.Map; + +/** + * gray rule. + * + * @author rong + */ +public interface GrayRule { + + /** + * gray rule match labels or not. + * + * @date 2024/3/14 + * @param labels conn labels. + * @return true if match, false otherwise. + */ + boolean match(Map labels); + + /** + * if the gray rule is valid. + * + * @date 2024/3/14 + * @return true if valid, false otherwise. + */ + boolean isValid(); + + /** + * get gray rule type. + * + * @date 2024/3/14 + * @return the gray rule type. + */ + String getType(); + + /** + * get gray rule version. + * + * @date 2024/3/14 + * @return the gray rule version. + */ + String getVersion(); + + /** + * get gray rule priority. + * + * @date 2024/3/14 + * @return the gray rule priority. + */ + int getPriority(); + + /** + * get raw String of gray rule. + * + * @date 2024/3/14 + * @return the raw String of gray rule. + */ + String getRawGrayRuleExp(); +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRuleManager.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRuleManager.java new file mode 100644 index 00000000000..7d8fbb72225 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/GrayRuleManager.java @@ -0,0 +1,114 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model.gray; + +import com.alibaba.nacos.common.spi.NacosServiceLoader; +import com.google.gson.Gson; + +import java.lang.reflect.Constructor; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * GrayRuleManager. + * + * @author zunfei.lzf + */ +public class GrayRuleManager { + + private static final Map> GRAY_RULE_MAP = new ConcurrentHashMap<>(8); + + public static final String SPLIT = "_"; + + static { + Collection grayRuleCollection = NacosServiceLoader.load(GrayRule.class); + for (GrayRule grayRule : grayRuleCollection) { + GRAY_RULE_MAP.put(grayRule.getType() + SPLIT + grayRule.getVersion(), grayRule.getClass()); + } + } + + /** + * get class by type and version. + * + * @param type type. + * @param version version. + * @return class. + * @date 2024/3/14 + */ + public static Class getClassByTypeAndVersion(String type, String version) { + return GRAY_RULE_MAP.get(type + SPLIT + version); + } + + /** + * construct gray rule. + * + * @param configGrayPersistInfo config gray persist info. + * @return gray rule. + * @date 2024/3/14 + */ + public static GrayRule constructGrayRule(ConfigGrayPersistInfo configGrayPersistInfo) { + Class classByTypeAndVersion = getClassByTypeAndVersion(configGrayPersistInfo.getType(), + configGrayPersistInfo.getVersion()); + if (classByTypeAndVersion == null) { + return null; + } + try { + Constructor declaredConstructor = classByTypeAndVersion.getDeclaredConstructor(String.class, int.class); + declaredConstructor.setAccessible(true); + return (GrayRule) declaredConstructor.newInstance(configGrayPersistInfo.getExpr(), + configGrayPersistInfo.getPriority()); + } catch (Exception e) { + throw new RuntimeException(String.format("construct gray rule failed with type[%s], version[%s].", + configGrayPersistInfo.getType(), configGrayPersistInfo.getVersion()), e); + } + } + + /** + * construct config gray persist info. + * + * @param grayRule gray rule. + * @return config gray persist info. + * @date 2024/3/14 + */ + public static ConfigGrayPersistInfo constructConfigGrayPersistInfo(GrayRule grayRule) { + return new ConfigGrayPersistInfo(grayRule.getType(), grayRule.getVersion(), grayRule.getRawGrayRuleExp(), + grayRule.getPriority()); + } + + /** + * deserialize config gray persist info. + * + * @param grayRuleRawStringFromDb gray rule raw string from db. + * @return config gray persist info. + * @date 2024/3/14 + */ + public static ConfigGrayPersistInfo deserializeConfigGrayPersistInfo(String grayRuleRawStringFromDb) { + return (new Gson()).fromJson(grayRuleRawStringFromDb, ConfigGrayPersistInfo.class); + } + + /** + * serialize config gray persist info. + * + * @param configGrayPersistInfo config gray persist info. + * @return serialized string. + * @date 2024/3/14 + */ + public static String serializeConfigGrayPersistInfo(ConfigGrayPersistInfo configGrayPersistInfo) { + return (new Gson()).toJson(configGrayPersistInfo); + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/TagGrayRule.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/TagGrayRule.java new file mode 100644 index 00000000000..5dcdc7a06fe --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/TagGrayRule.java @@ -0,0 +1,90 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model.gray; + +import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.utils.StringUtils; + +import java.util.Map; +import java.util.Objects; + +import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG; + +/** + * Tag gray rule. + * @author shiyiyue + */ +public class TagGrayRule extends AbstractGrayRule { + + String tagValue; + + public static final String VIP_SERVER_TAG_LABEL = VIPSERVER_TAG; + + public static final String TYPE_TAG = "tag"; + + public static final String VERSION = "1.0.0"; + + public static final int PROPRITY = -999; + + public TagGrayRule() { + super(); + } + + public TagGrayRule(String rawGrayRuleExp, int priority) { + super(rawGrayRuleExp, priority); + } + + @Override + protected void parse(String rawGrayRule) throws NacosException { + if (StringUtils.isBlank(rawGrayRule)) { + return; + } + this.tagValue = rawGrayRule; + } + + @Override + public boolean match(Map labels) { + return labels.containsKey(VIP_SERVER_TAG_LABEL) && tagValue.equals(labels.get(VIP_SERVER_TAG_LABEL)); + } + + @Override + public String getType() { + return TYPE_TAG; + } + + @Override + public String getVersion() { + return VERSION; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TagGrayRule that = (TagGrayRule) o; + return tagValue.equals(that.tagValue); + } + + @Override + public int hashCode() { + return Objects.hash(tagValue); + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeBatchListenRequestHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeBatchListenRequestHandler.java index f7bc8a55d8a..aa8648921e0 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeBatchListenRequestHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeBatchListenRequestHandler.java @@ -57,17 +57,17 @@ public ConfigChangeBatchListenResponse handle(ConfigBatchListenRequest configCha String tag = configChangeListenRequest.getHeader(Constants.VIPSERVER_TAG); ConfigChangeBatchListenResponse configChangeBatchListenResponse = new ConfigChangeBatchListenResponse(); - for (ConfigBatchListenRequest.ConfigListenContext listenContext : configChangeListenRequest - .getConfigListenContexts()) { - String groupKey = GroupKey2 - .getKey(listenContext.getDataId(), listenContext.getGroup(), listenContext.getTenant()); + for (ConfigBatchListenRequest.ConfigListenContext listenContext : configChangeListenRequest.getConfigListenContexts()) { + String groupKey = GroupKey2.getKey(listenContext.getDataId(), listenContext.getGroup(), + listenContext.getTenant()); groupKey = StringPool.get(groupKey); String md5 = StringPool.get(listenContext.getMd5()); if (configChangeListenRequest.isListen()) { configChangeListenContext.addListen(groupKey, md5, connectionId); - boolean isUptoDate = ConfigCacheService.isUptodate(groupKey, md5, meta.getClientIp(), tag); + boolean isUptoDate = ConfigCacheService.isUptodate(groupKey, md5, meta.getClientIp(), tag, + meta.getAppLabels()); if (!isUptoDate) { configChangeBatchListenResponse.addChangeConfig(listenContext.getDataId(), listenContext.getGroup(), listenContext.getTenant()); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandler.java index cc284f1db2c..a88f4c1ed69 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandler.java @@ -16,12 +16,19 @@ package com.alibaba.nacos.config.server.remote; +import com.alibaba.nacos.api.ability.constant.AbilityKey; +import com.alibaba.nacos.api.ability.constant.AbilityStatus; import com.alibaba.nacos.api.config.remote.request.cluster.ConfigChangeClusterSyncRequest; import com.alibaba.nacos.api.config.remote.response.cluster.ConfigChangeClusterSyncResponse; import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.remote.request.RequestMeta; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; +import com.alibaba.nacos.config.server.service.ConfigGrayModelMigrateService; import com.alibaba.nacos.config.server.service.dump.DumpRequest; import com.alibaba.nacos.config.server.service.dump.DumpService; +import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.core.paramcheck.ExtractorManager; import com.alibaba.nacos.core.paramcheck.impl.ConfigRequestParamExtractor; import com.alibaba.nacos.core.remote.RequestHandler; @@ -40,8 +47,12 @@ public class ConfigChangeClusterSyncRequestHandler private final DumpService dumpService; - public ConfigChangeClusterSyncRequestHandler(DumpService dumpService) { + private ConfigGrayModelMigrateService configGrayModelMigrateService; + + public ConfigChangeClusterSyncRequestHandler(DumpService dumpService, + ConfigGrayModelMigrateService configGrayModelMigrateService) { this.dumpService = dumpService; + this.configGrayModelMigrateService = configGrayModelMigrateService; } @TpsControl(pointName = "ClusterConfigChangeNotify") @@ -49,15 +60,38 @@ public ConfigChangeClusterSyncRequestHandler(DumpService dumpService) { @ExtractorManager.Extractor(rpcExtractor = ConfigRequestParamExtractor.class) public ConfigChangeClusterSyncResponse handle(ConfigChangeClusterSyncRequest configChangeSyncRequest, RequestMeta meta) throws NacosException { - + DumpRequest dumpRequest = DumpRequest.create(configChangeSyncRequest.getDataId(), configChangeSyncRequest.getGroup(), configChangeSyncRequest.getTenant(), configChangeSyncRequest.getLastModified(), meta.getClientIp()); - dumpRequest.setBeta(configChangeSyncRequest.isBeta()); - dumpRequest.setBatch(configChangeSyncRequest.isBatch()); - dumpRequest.setTag(configChangeSyncRequest.getTag()); + if (PropertyUtil.isGrayCompatibleModel()) { + if (configChangeSyncRequest.isBeta() || StringUtils.isNotBlank(configChangeSyncRequest.getTag())) { + if (supportNewGrayModel(meta)) { + //capability model from new server,ignore. + return new ConfigChangeClusterSyncResponse(); + } else { + String grayName = null; + //from old server ,try migrate and transfer gray model. + if (configChangeSyncRequest.isBeta()) { + configGrayModelMigrateService.checkMigrateBeta(configChangeSyncRequest.getDataId(), + configChangeSyncRequest.getGroup(), configChangeSyncRequest.getTenant()); + grayName = BetaGrayRule.TYPE_BETA; + } else { + configGrayModelMigrateService.checkMigrateTag(configChangeSyncRequest.getDataId(), + configChangeSyncRequest.getGroup(), configChangeSyncRequest.getTenant(), + configChangeSyncRequest.getTag()); + grayName = TagGrayRule.TYPE_TAG + "_" + configChangeSyncRequest.getTag(); + } + configChangeSyncRequest.setGrayName(grayName); + } + } + } + dumpRequest.setGrayName(configChangeSyncRequest.getGrayName()); dumpService.dump(dumpRequest); return new ConfigChangeClusterSyncResponse(); } + private boolean supportNewGrayModel(RequestMeta meta) { + return AbilityStatus.SUPPORTED.equals(meta.getConnectionAbility(AbilityKey.SUPPORT_NEW_GRAY_MODEL)); + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandler.java index 82ca984b97d..83af673362b 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandler.java @@ -16,23 +16,20 @@ package com.alibaba.nacos.config.server.remote; +import com.alibaba.nacos.api.common.Constants; +import com.alibaba.nacos.api.config.ConfigType; import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest; import com.alibaba.nacos.api.config.remote.response.ConfigPublishResponse; import com.alibaba.nacos.api.exception.NacosException; +import com.alibaba.nacos.api.exception.api.NacosApiException; import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.api.remote.response.ResponseCode; import com.alibaba.nacos.auth.annotation.Secured; -import com.alibaba.nacos.common.utils.MapUtil; +import com.alibaba.nacos.common.utils.Pair; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.config.server.model.ConfigInfo; -import com.alibaba.nacos.config.server.model.ConfigOperateResult; -import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; -import com.alibaba.nacos.config.server.service.AggrWhitelist; -import com.alibaba.nacos.config.server.service.ConfigChangePublisher; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; -import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; +import com.alibaba.nacos.config.server.model.ConfigRequestInfo; +import com.alibaba.nacos.config.server.model.form.ConfigForm; +import com.alibaba.nacos.config.server.service.ConfigOperationService; import com.alibaba.nacos.config.server.utils.ParamUtils; import com.alibaba.nacos.core.control.TpsControl; import com.alibaba.nacos.core.paramcheck.ExtractorManager; @@ -41,11 +38,9 @@ import com.alibaba.nacos.core.utils.Loggers; import com.alibaba.nacos.plugin.auth.constant.ActionTypes; import com.alibaba.nacos.plugin.auth.constant.SignType; +import com.alibaba.nacos.plugin.encryption.handler.EncryptionHandler; import org.springframework.stereotype.Component; -import java.util.HashMap; -import java.util.Map; - /** * request handler to publish config. * @@ -55,18 +50,10 @@ @Component public class ConfigPublishRequestHandler extends RequestHandler { - private final ConfigInfoPersistService configInfoPersistService; - - private final ConfigInfoTagPersistService configInfoTagPersistService; + private ConfigOperationService configOperationService; - private final ConfigInfoBetaPersistService configInfoBetaPersistService; - - public ConfigPublishRequestHandler(ConfigInfoPersistService configInfoPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService) { - this.configInfoPersistService = configInfoPersistService; - this.configInfoTagPersistService = configInfoTagPersistService; - this.configInfoBetaPersistService = configInfoBetaPersistService; + public ConfigPublishRequestHandler(ConfigOperationService configOperationService) { + this.configOperationService = configOperationService; } @Override @@ -82,7 +69,6 @@ public ConfigPublishResponse handle(ConfigPublishRequest request, RequestMeta me final String tenant = request.getTenant(); final String srcIp = meta.getClientIp(); - final String requestIpApp = request.getAdditionParam("requestIpApp"); final String tag = request.getAdditionParam("tag"); final String appName = request.getAdditionParam("appName"); final String type = request.getAdditionParam("type"); @@ -92,82 +78,49 @@ public ConfigPublishResponse handle(ConfigPublishRequest request, RequestMeta me // check tenant ParamUtils.checkParam(dataId, group, "datumId", content); ParamUtils.checkParam(tag); - Map configAdvanceInfo = new HashMap<>(10); - MapUtil.putIfValNoNull(configAdvanceInfo, "config_tags", request.getAdditionParam("config_tags")); - MapUtil.putIfValNoNull(configAdvanceInfo, "desc", request.getAdditionParam("desc")); - MapUtil.putIfValNoNull(configAdvanceInfo, "use", request.getAdditionParam("use")); - MapUtil.putIfValNoNull(configAdvanceInfo, "effect", request.getAdditionParam("effect")); - MapUtil.putIfValNoNull(configAdvanceInfo, "type", type); - MapUtil.putIfValNoNull(configAdvanceInfo, "schema", request.getAdditionParam("schema")); - ParamUtils.checkParam(configAdvanceInfo); - if (AggrWhitelist.isAggrDataId(dataId)) { - Loggers.REMOTE_DIGEST.warn("[aggr-conflict] {} attempt to publish single data, {}, {}", srcIp, dataId, - group); - throw new NacosException(NacosException.NO_RIGHT, "dataId:" + dataId + " is aggr"); + ConfigForm configForm = new ConfigForm(); + configForm.setDataId(dataId); + configForm.setGroup(group); + configForm.setNamespaceId(tenant); + configForm.setContent(content); + configForm.setTag(tag); + configForm.setAppName(appName); + configForm.setSrcUser(srcUser); + configForm.setConfigTags(request.getAdditionParam("config_tags")); + configForm.setDesc(request.getAdditionParam("desc")); + configForm.setUse(request.getAdditionParam("use")); + configForm.setEffect(request.getAdditionParam("effect")); + configForm.setType(type); + configForm.setSchema(request.getAdditionParam("schema")); + + if (!ConfigType.isValidType(type)) { + configForm.setType(ConfigType.getDefaultType().getType()); } - ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); - configInfo.setMd5(request.getCasMd5()); - configInfo.setType(type); - configInfo.setEncryptedDataKey(encryptedDataKey); - String betaIps = request.getAdditionParam("betaIps"); - ConfigOperateResult configOperateResult = null; - String persistEvent = ConfigTraceService.PERSISTENCE_EVENT; - if (StringUtils.isBlank(betaIps)) { - if (StringUtils.isBlank(tag)) { - if (StringUtils.isNotBlank(request.getCasMd5())) { - configOperateResult = configInfoPersistService.insertOrUpdateCas(srcIp, srcUser, configInfo, - configAdvanceInfo); - if (!configOperateResult.isSuccess()) { - return ConfigPublishResponse.buildFailResponse(ResponseCode.FAIL.getCode(), - "Cas publish fail,server md5 may have changed."); - } - } else { - configOperateResult = configInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, - configAdvanceInfo); - } - ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, - configOperateResult.getLastModified())); - } else { - if (StringUtils.isNotBlank(request.getCasMd5())) { - configOperateResult = configInfoTagPersistService.insertOrUpdateTagCas(configInfo, tag, srcIp, - srcUser); - if (!configOperateResult.isSuccess()) { - return ConfigPublishResponse.buildFailResponse(ResponseCode.FAIL.getCode(), - "Cas publish tag config fail,server md5 may have changed."); - } - } else { - configOperateResult = configInfoTagPersistService.insertOrUpdateTag(configInfo, tag, srcIp, - srcUser); - } - persistEvent = ConfigTraceService.PERSISTENCE_EVENT_TAG + "-" + tag; - ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(false, dataId, group, tenant, tag, - configOperateResult.getLastModified())); - } + ConfigRequestInfo configRequestInfo = new ConfigRequestInfo(); + configRequestInfo.setSrcIp(srcIp); + configRequestInfo.setRequestIpApp(meta.getLabels().get(Constants.APPNAME)); + configRequestInfo.setBetaIps(request.getAdditionParam("betaIps")); + configRequestInfo.setCasMd5(request.getCasMd5()); + + String encryptedDataKeyFinal = null; + if (StringUtils.isNotBlank(encryptedDataKey)) { + encryptedDataKeyFinal = encryptedDataKey; } else { - // beta publish - if (StringUtils.isNotBlank(request.getCasMd5())) { - configOperateResult = configInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, betaIps, srcIp, - srcUser); - if (!configOperateResult.isSuccess()) { - return ConfigPublishResponse.buildFailResponse(ResponseCode.FAIL.getCode(), - "Cas publish beta config fail,server md5 may have changed."); - } - } else { - configOperateResult = configInfoBetaPersistService.insertOrUpdateBeta(configInfo, betaIps, srcIp, - srcUser); - } - persistEvent = ConfigTraceService.PERSISTENCE_EVENT_BETA; - - ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(true, dataId, group, tenant, configOperateResult.getLastModified())); + Pair pair = EncryptionHandler.encryptHandler(dataId, content); + content = pair.getSecond(); + encryptedDataKeyFinal = pair.getFirst(); + configForm.setContent(content); + } + try { + configOperationService.publishConfig(configForm, configRequestInfo, encryptedDataKeyFinal); + return ConfigPublishResponse.buildSuccessResponse(); + } catch (NacosApiException nacosApiException) { + return ConfigPublishResponse.buildFailResponse(ResponseCode.FAIL.getCode(), + nacosApiException.getErrMsg()); } - ConfigTraceService.logPersistenceEvent(dataId, group, tenant, requestIpApp, - configOperateResult.getLastModified(), srcIp, persistEvent, ConfigTraceService.PERSISTENCE_TYPE_PUB, - content); - return ConfigPublishResponse.buildSuccessResponse(); + } catch (Exception e) { Loggers.REMOTE_DIGEST.error("[ConfigPublishRequestHandler] publish config error ,request ={}", request, e); return ConfigPublishResponse.buildFailResponse( diff --git a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java index e1f0a93b23d..5423870af4a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandler.java @@ -24,6 +24,9 @@ import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.model.CacheItem; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; @@ -39,7 +42,10 @@ import org.springframework.stereotype.Component; import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import static com.alibaba.nacos.api.common.Constants.CLIENT_IP; import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_UTF8; import static com.alibaba.nacos.config.server.utils.LogUtil.PULL_LOG; import static com.alibaba.nacos.config.server.utils.RequestUtil.CLIENT_APPNAME_HEADER; @@ -80,7 +86,6 @@ private ConfigQueryResponse getContext(ConfigQueryRequest configQueryRequest, Re String groupKey = GroupKey2.getKey(configQueryRequest.getDataId(), configQueryRequest.getGroup(), configQueryRequest.getTenant()); - String autoTag = configQueryRequest.getHeader(com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG); String requestIpApp = meta.getLabels().get(CLIENT_APPNAME_HEADER); String acceptCharset = ENCODE_UTF8; @@ -94,48 +99,62 @@ private ConfigQueryResponse getContext(ConfigQueryRequest configQueryRequest, Re if (lockResult > 0 && cacheItem != null) { try { long lastModified = 0L; - boolean isBeta = cacheItem.isBeta() && cacheItem.getIps4Beta() != null && cacheItem.getIps4Beta() - .contains(clientIp) && cacheItem.getConfigCacheBeta() != null; String configType = cacheItem.getType(); response.setContentType((null != configType) ? configType : "text"); String content; String md5; String encryptedDataKey; - if (isBeta) { - md5 = cacheItem.getConfigCacheBeta().getMd5(acceptCharset); - lastModified = cacheItem.getConfigCacheBeta().getLastModifiedTs(); - content = ConfigDiskServiceFactory.getInstance().getBetaContent(dataId, group, tenant); - pullEvent = ConfigTraceService.PULL_EVENT_BETA; - encryptedDataKey = cacheItem.getConfigCacheBeta().getEncryptedDataKey(); - response.setBeta(true); + ConfigCacheGray matchedGray = null; + Map appLabels = null; + boolean specificTag = StringUtils.isNotBlank(tag); + if (specificTag) { + appLabels = new HashMap<>(4); + appLabels.put(TagGrayRule.VIP_SERVER_TAG_LABEL, tag); + appLabels.put(CLIENT_IP, clientIp); } else { - if (StringUtils.isBlank(tag)) { - if (isUseTag(cacheItem, autoTag)) { - md5 = cacheItem.getTagMd5(autoTag, acceptCharset); - lastModified = cacheItem.getTagLastModified(autoTag); - encryptedDataKey = cacheItem.getTagEncryptedDataKey(autoTag); - content = ConfigDiskServiceFactory.getInstance() - .getTagContent(dataId, group, tenant, autoTag); - pullEvent = ConfigTraceService.PULL_EVENT_TAG + "-" + autoTag; - response.setTag(URLEncoder.encode(autoTag, ENCODE_UTF8)); - - } else { - md5 = cacheItem.getConfigCache().getMd5(acceptCharset); - lastModified = cacheItem.getConfigCache().getLastModifiedTs(); - encryptedDataKey = cacheItem.getConfigCache().getEncryptedDataKey(); - content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); - pullEvent = ConfigTraceService.PULL_EVENT; + appLabels = new HashMap(meta.getAppLabels()); + if (!appLabels.containsKey(CLIENT_IP)) { + appLabels.put(CLIENT_IP, clientIp); + } + } + + if (cacheItem.getSortConfigGrays() != null && !cacheItem.getSortConfigGrays().isEmpty()) { + for (ConfigCacheGray configCacheGray : cacheItem.getSortConfigGrays()) { + if (configCacheGray.match(appLabels)) { + matchedGray = configCacheGray; + break; } - } else { - md5 = cacheItem.getTagMd5(tag, acceptCharset); - lastModified = cacheItem.getTagLastModified(tag); - encryptedDataKey = cacheItem.getTagEncryptedDataKey(tag); - content = ConfigDiskServiceFactory.getInstance().getTagContent(dataId, group, tenant, tag); - response.setTag(tag); - pullEvent = ConfigTraceService.PULL_EVENT_TAG + "-" + tag; } } + if (matchedGray != null) { + md5 = matchedGray.getMd5(acceptCharset); + lastModified = matchedGray.getLastModifiedTs(); + encryptedDataKey = matchedGray.getEncryptedDataKey(); + content = ConfigDiskServiceFactory.getInstance() + .getGrayContent(dataId, group, tenant, matchedGray.getGrayName()); + pullEvent = ConfigTraceService.PULL_EVENT + "-" + matchedGray.getGrayName(); + if (BetaGrayRule.TYPE_BETA.equals(matchedGray.getGrayName())) { + response.setBeta(true); + } + if (TagGrayRule.TYPE_TAG.equals(matchedGray.getGrayRule().getType())) { + response.setTag(URLEncoder.encode(matchedGray.getRawGrayRule(), ENCODE_UTF8)); + } + } else if (specificTag) { + //specific tag is not found + md5 = null; + lastModified = 0L; + encryptedDataKey = null; + content = null; + pullEvent = ConfigTraceService.PULL_EVENT + "-" + TagGrayRule.TYPE_TAG + "-" + tag; + response.setTag(tag); + } else { + md5 = cacheItem.getConfigCache().getMd5(acceptCharset); + lastModified = cacheItem.getConfigCache().getLastModifiedTs(); + encryptedDataKey = cacheItem.getConfigCache().getEncryptedDataKey(); + content = ConfigDiskServiceFactory.getInstance().getContent(dataId, group, tenant); + pullEvent = ConfigTraceService.PULL_EVENT; + } response.setMd5(md5); response.setEncryptedDataKey(encryptedDataKey); @@ -170,9 +189,4 @@ private ConfigQueryResponse getContext(ConfigQueryRequest configQueryRequest, Re return response; } - private static boolean isUseTag(CacheItem cacheItem, String tag) { - return StringUtils.isNotBlank(tag) && cacheItem.getConfigCacheTags() != null && cacheItem.getConfigCacheTags() - .containsKey(tag); - } - } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifier.java b/config/src/main/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifier.java index bd47f8f09ef..e6f7517aafb 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifier.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifier.java @@ -22,7 +22,6 @@ import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.CollectionUtils; -import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.configuration.ConfigCommonConfig; import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent; import com.alibaba.nacos.config.server.utils.ConfigExecutor; @@ -39,7 +38,6 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; -import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -86,8 +84,7 @@ void registerTpsPoint() { * * @param groupKey groupKey */ - public void configDataChanged(String groupKey, String dataId, String group, String tenant, boolean isBeta, - List betaIps, String tag) { + public void configDataChanged(String groupKey, String dataId, String group, String tenant) { Set listeners = configChangeListenContext.getListeners(groupKey); if (CollectionUtils.isEmpty(listeners)) { @@ -102,12 +99,6 @@ public void configDataChanged(String groupKey, String dataId, String group, Stri ConnectionMeta metaInfo = connection.getMetaInfo(); String clientIp = metaInfo.getClientIp(); - String clientTag = metaInfo.getTag(); - - //tag check - if (StringUtils.isNotBlank(tag) && !tag.equals(clientTag)) { - continue; - } ConfigChangeNotifyRequest notifyRequest = ConfigChangeNotifyRequest.build(dataId, group, tenant); @@ -122,15 +113,13 @@ public void configDataChanged(String groupKey, String dataId, String group, Stri @Override public void onEvent(LocalDataChangeEvent event) { String groupKey = event.groupKey; - boolean isBeta = event.isBeta; - List betaIps = event.betaIps; + String[] strings = GroupKey.parseKey(groupKey); String dataId = strings[0]; String group = strings[1]; String tenant = strings.length > 2 ? strings[2] : ""; - String tag = event.tag; - configDataChanged(groupKey, dataId, group, tenant, isBeta, betaIps, tag); + configDataChanged(groupKey, dataId, group, tenant); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java index beb7c6e6181..528fad40f3d 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigCacheService.java @@ -17,26 +17,28 @@ package com.alibaba.nacos.config.server.service; import com.alibaba.nacos.common.notify.NotifyCenter; -import com.alibaba.nacos.common.utils.CollectionUtils; -import com.alibaba.nacos.common.utils.InternetAddressUtil; import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.CacheItem; import com.alibaba.nacos.config.server.model.ConfigCache; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent; +import com.alibaba.nacos.config.server.model.gray.GrayRule; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.sys.env.EnvUtil; -import com.google.common.collect.Lists; import java.io.IOException; -import java.util.Collections; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import static com.alibaba.nacos.api.common.Constants.CLIENT_IP; +import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG; import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_UTF8; +import static com.alibaba.nacos.config.server.constant.Constants.NULL; import static com.alibaba.nacos.config.server.constant.Constants.PERSIST_ENCODE; import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; import static com.alibaba.nacos.config.server.utils.LogUtil.DUMP_LOG; @@ -171,147 +173,80 @@ public static boolean dump(String dataId, String group, String tenant, String co } /** - * Save config file and update md5 value in cache. + * Save gray config file and update md5 value in cache. * * @param dataId dataId string value. * @param group group string value. * @param tenant tenant string value. + * @param grayName grayName string value. + * @param grayRule grayRule string value. * @param content content string value. * @param lastModifiedTs lastModifiedTs. - * @param betaIps betaIps string value. * @return dumpChange success or not. */ - public static boolean dumpBeta(String dataId, String group, String tenant, String content, long lastModifiedTs, - String betaIps, String encryptedDataKey) { + public static boolean dumpGray(String dataId, String group, String tenant, String grayName, String grayRule, + String content, long lastModifiedTs, String encryptedDataKey) { final String groupKey = GroupKey2.getKey(dataId, group, tenant); makeSure(groupKey, null); final int lockResult = tryWriteLock(groupKey); if (lockResult < 0) { - DUMP_LOG.warn("[dump-beta-error] write lock failed. {}", groupKey); + DUMP_LOG.warn("[dump-gray-error] write lock failed. {}", groupKey); return false; } try { //check timestamp - boolean timestampOutDated = lastModifiedTs < ConfigCacheService.getBetaLastModifiedTs(groupKey); - if (timestampOutDated) { - DUMP_LOG.warn("[dump-beta-ignore] timestamp is outdated,groupKey={}", groupKey); - return true; - } + long localGrayLastModifiedTs = ConfigCacheService.getGrayLastModifiedTs(groupKey, grayName); - boolean timestampUpdated = lastModifiedTs > ConfigCacheService.getBetaLastModifiedTs(groupKey); - - String[] betaIpsArr = betaIps.split(","); - List betaIpList = Lists.newArrayList(betaIpsArr); - String md5 = MD5Utils.md5Hex(content, ENCODE_UTF8); - - //md5 check & update local disk cache. - String localContentBetaMd5 = ConfigCacheService.getContentBetaMd5(groupKey); - boolean md5Changed = !md5.equals(localContentBetaMd5); - if (md5Changed) { - DUMP_LOG.info( - "[dump-beta] md5 changed, update md5 in local disk cache. groupKey={}, newMd5={}, oldMd5={}", - groupKey, md5, localContentBetaMd5); - ConfigDiskServiceFactory.getInstance().saveBetaToDisk(dataId, group, tenant, content); - } - - //md5 , ip list timestamp check and update local jvm cache. - boolean ipListChanged = !betaIpList.equals(ConfigCacheService.getBetaIps(groupKey)); - if (md5Changed) { - DUMP_LOG.info( - "[dump-beta] md5 changed, update md5 & ip list & timestamp in jvm cache. groupKey={}, newMd5={}, oldMd5={},lastModifiedTs={}", - groupKey, md5, localContentBetaMd5, lastModifiedTs); - updateBetaMd5(groupKey, md5, betaIpList, lastModifiedTs, encryptedDataKey); - } else if (ipListChanged) { - DUMP_LOG.warn("[dump-beta] ip list changed, update ip list & timestamp in jvm cache. groupKey={}," - + " newIpList={}, oldIpList={},lastModifiedTs={}", groupKey, betaIpList, - ConfigCacheService.getBetaIps(groupKey), lastModifiedTs); - updateBetaIpList(groupKey, betaIpList, lastModifiedTs); - } else if (timestampUpdated) { - DUMP_LOG.warn( - "[dump-beta] timestamp changed, update timestamp in jvm cache. groupKey={}, newLastModifiedTs={}, oldLastModifiedTs={}", - groupKey, lastModifiedTs, ConfigCacheService.getBetaLastModifiedTs(groupKey)); - updateBetaTimeStamp(groupKey, lastModifiedTs); - } else { - DUMP_LOG.warn( - "[dump-beta-ignore] ignore to save jvm cache, md5 & ip list & timestamp no changed. groupKey={}", - groupKey); - } - return true; - } catch (IOException ioe) { - DUMP_LOG.error("[dump-beta-exception] save disk error. " + groupKey + ", " + ioe.toString(), ioe); - return false; - } finally { - releaseWriteLock(groupKey); - } - } - - /** - * Save config file and update md5 value in cache. - * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. - * @param content content string value. - * @param lastModifiedTs lastModifiedTs. - * @param tag tag string value. - * @return dumpChange success or not. - */ - public static boolean dumpTag(String dataId, String group, String tenant, String tag, String content, - long lastModifiedTs, String encryptedDataKey4Tag) { - final String groupKey = GroupKey2.getKey(dataId, group, tenant); - - makeSure(groupKey, null); - final int lockResult = tryWriteLock(groupKey); - - if (lockResult < 0) { - DUMP_LOG.warn("[dump-tag-error] write lock failed. {}", groupKey); - return false; - } - - try { - - //check timestamp - long localTagLastModifiedTs = ConfigCacheService.getTagLastModifiedTs(groupKey, tag); - - boolean timestampOutdated = lastModifiedTs < localTagLastModifiedTs; + boolean timestampOutdated = lastModifiedTs < localGrayLastModifiedTs; if (timestampOutdated) { - DUMP_LOG.warn("[dump-tag-ignore] timestamp is outdated,groupKey={}", groupKey); + DUMP_LOG.warn("[dump-gray-ignore] timestamp is outdated,groupKey={}", groupKey); return true; } - boolean timestampChanged = lastModifiedTs > localTagLastModifiedTs; + boolean timestampChanged = lastModifiedTs > localGrayLastModifiedTs; final String md5 = MD5Utils.md5Hex(content, ENCODE_UTF8); - String localContentTagMd5 = ConfigCacheService.getContentTagMd5(groupKey, tag); - boolean md5Changed = !md5.equals(localContentTagMd5); + String localContentGrayMd5 = ConfigCacheService.getContentGrayMd5(groupKey, grayName); + boolean md5Changed = !md5.equals(localContentGrayMd5); - if (md5Changed) { - ConfigDiskServiceFactory.getInstance().saveTagToDisk(dataId, group, tenant, tag, content); - } + GrayRule localGrayRule = ConfigCacheService.getGrayRule(groupKey, grayName); + GrayRule grayRuleNew = GrayRuleManager.constructGrayRule( + GrayRuleManager.deserializeConfigGrayPersistInfo(grayRule)); + + boolean grayRuleChanged = !grayRuleNew.equals(localGrayRule); if (md5Changed) { - DUMP_LOG.warn( - "[dump-tag] md5 changed, update local jvm cache, groupKey={},tag={}, newMd5={},oldMd5={},lastModifiedTs={}", - groupKey, tag, md5, localContentTagMd5, lastModifiedTs); - updateTagMd5(groupKey, tag, md5, lastModifiedTs, encryptedDataKey4Tag); + DUMP_LOG.info( + "[dump-gray] md5 changed, update local jvm cache& local disk cache, groupKey={},grayName={}, " + + "newMd5={},oldMd5={}, newGrayRule={}, oldGrayRule={},lastModifiedTs={}", groupKey, + grayName, md5, localContentGrayMd5, grayRule, localGrayRule, lastModifiedTs); + updateGrayMd5(groupKey, grayName, grayRule, md5, lastModifiedTs, encryptedDataKey); + ConfigDiskServiceFactory.getInstance().saveGrayToDisk(dataId, group, tenant, grayName, content); + + } else if (grayRuleChanged) { + DUMP_LOG.info("[dump-gray] gray rule changed, update local jvm cache, groupKey={},grayName={}, " + + "newMd5={},oldMd5={}, newGrayRule={}, oldGrayRule={},lastModifiedTs={}", groupKey, grayName, + md5, localContentGrayMd5, grayRule, localGrayRule, lastModifiedTs); + updateGrayRule(groupKey, grayName, grayRule, lastModifiedTs, encryptedDataKey); } else if (timestampChanged) { - DUMP_LOG.warn( - "[dump-tag] timestamp changed, update last modified in local jvm cache, groupKey={},tag={}," - + "tagLastModifiedTs={},oldTagLastModifiedTs={}", groupKey, tag, lastModifiedTs, - localTagLastModifiedTs); - updateTagTimeStamp(groupKey, tag, lastModifiedTs); + DUMP_LOG.info( + "[dump-gray] timestamp changed, update last modified in local jvm cache, groupKey={},grayName={}," + + "grayLastModifiedTs={},oldgrayLastModifiedTs={}", groupKey, grayName, lastModifiedTs, + localGrayLastModifiedTs); + updateGrayTimeStamp(groupKey, grayName, lastModifiedTs); } else { - DUMP_LOG.warn("[dump-tag-ignore] md5 & timestamp not changed. groupKey={},tag={}", groupKey, tag); + DUMP_LOG.warn("[dump-gray-ignore] md5 & timestamp not changed. groupKey={},grayName={}", groupKey, + grayName); } return true; } catch (IOException ioe) { - DUMP_LOG.error("[dump-tag-exception] save disk error. " + groupKey + ", " + ioe.toString(), ioe); + DUMP_LOG.error("[dump-gray-exception] save disk error. " + groupKey + ", " + ioe.toString(), ioe); return false; } finally { releaseWriteLock(groupKey); @@ -319,14 +254,15 @@ public static boolean dumpTag(String dataId, String group, String tenant, String } /** - * Delete config file, and delete cache. + * Delete gray config file, and delete cache. * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. + * @param dataId dataId string value. + * @param group group string value. + * @param tenant tenant string value. + * @param grayName grayName string value. * @return remove success or not. */ - public static boolean remove(String dataId, String group, String tenant) { + public static boolean removeGray(String dataId, String group, String tenant, String grayName) { final String groupKey = GroupKey2.getKey(dataId, group, tenant); final int lockResult = tryWriteLock(groupKey); @@ -343,51 +279,22 @@ public static boolean remove(String dataId, String group, String tenant) { } try { - DUMP_LOG.info("[dump] remove local disk cache,groupKey={} ", groupKey); - ConfigDiskServiceFactory.getInstance().removeConfigInfo(dataId, group, tenant); - - CACHE.remove(groupKey); - DUMP_LOG.info("[dump] remove local jvm cache,groupKey={} ", groupKey); + DUMP_LOG.info("[remove-gray-ok] remove gray in local disk cache,grayName={},groupKey={} ", grayName, + groupKey); + ConfigDiskServiceFactory.getInstance().removeConfigInfo4Gray(dataId, group, tenant, grayName); - NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); + CacheItem ci = CACHE.get(groupKey); + if (ci.getConfigCacheGray() != null) { + ci.getConfigCacheGray().remove(grayName); + if (ci.getConfigCacheGray().isEmpty()) { + ci.clearConfigGrays(); + } + } - return true; - } finally { - releaseWriteLock(groupKey); - } - } - - /** - * Delete beta config file, and delete cache. - * - * @param dataId dataId string value. - * @param group group string value. - * @param tenant tenant string value. - * @return remove success or not. - */ - public static boolean removeBeta(String dataId, String group, String tenant) { - final String groupKey = GroupKey2.getKey(dataId, group, tenant); - final int lockResult = tryWriteLock(groupKey); - - // If data is non-existent. - if (0 == lockResult) { - DUMP_LOG.info("[remove-ok] {} not exist.", groupKey); - return true; - } - - // try to lock failed - if (lockResult < 0) { - DUMP_LOG.warn("[remove-error] write lock failed. {}", groupKey); - return false; - } - - try { - DUMP_LOG.info("[remove-beta-ok] remove beta in local disk cache,groupKey={} ", groupKey); - ConfigDiskServiceFactory.getInstance().removeConfigInfo4Beta(dataId, group, tenant); - NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, CACHE.get(groupKey).getIps4Beta())); - CACHE.get(groupKey).removeBeta(); - DUMP_LOG.info("[remove-beta-ok] remove beta in local jvm cache,groupKey={} ", groupKey); + DUMP_LOG.info("[remove-gray-ok] remove gray in local jvm cache,grayName={},groupKey={} ", grayName, + groupKey); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); return true; } finally { releaseWriteLock(groupKey); @@ -395,15 +302,14 @@ public static boolean removeBeta(String dataId, String group, String tenant) { } /** - * Delete tag config file, and delete cache. + * Delete config file, and delete cache. * * @param dataId dataId string value. * @param group group string value. * @param tenant tenant string value. - * @param tag tag string value. * @return remove success or not. */ - public static boolean removeTag(String dataId, String group, String tenant, String tag) { + public static boolean remove(String dataId, String group, String tenant) { final String groupKey = GroupKey2.getKey(dataId, group, tenant); final int lockResult = tryWriteLock(groupKey); @@ -420,20 +326,14 @@ public static boolean removeTag(String dataId, String group, String tenant, Stri } try { - DUMP_LOG.info("[remove-tag-ok] remove tag in local disk cache,tag={},groupKey={} ", tag, groupKey); - ConfigDiskServiceFactory.getInstance().removeConfigInfo4Tag(dataId, group, tenant, tag); + DUMP_LOG.info("[dump] remove local disk cache,groupKey={} ", groupKey); + ConfigDiskServiceFactory.getInstance().removeConfigInfo(dataId, group, tenant); - CacheItem ci = CACHE.get(groupKey); - if (ci.getConfigCacheTags() != null) { - ci.getConfigCacheTags().remove(tag); - if (ci.getConfigCacheTags().isEmpty()) { - ci.clearConfigTags(); - } - } + CACHE.remove(groupKey); + DUMP_LOG.info("[dump] remove local jvm cache,groupKey={} ", groupKey); - DUMP_LOG.info("[remove-tag-ok] remove tag in local jvm cache,tag={},groupKey={} ", tag, groupKey); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); - NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, tag)); return true; } finally { releaseWriteLock(groupKey); @@ -458,126 +358,112 @@ public static void updateMd5(String groupKey, String md5Utf8, long lastModifiedT } /** - * Update Beta md5 value. + * Update gray md5 value. * - * @param groupKey groupKey string value. - * @param md5Utf8 md5UTF8 string value. - * @param ips4Beta ips4Beta List. - * @param lastModifiedTs lastModifiedTs long value. + * @param groupKey groupKey string value. + * @param grayName grayName string value. + * @param grayRule grayRule string value. + * @param md5Utf8 md5UTF8 string value. + * @param lastModifiedTs lastModifiedTs long value. + * @param encryptedDataKey encryptedDataKey string value. */ - public static void updateBetaMd5(String groupKey, String md5Utf8, List ips4Beta, long lastModifiedTs, - String encryptedDataKey4Beta) { + private static void updateGrayMd5(String groupKey, String grayName, String grayRule, String md5Utf8, + long lastModifiedTs, String encryptedDataKey) { CacheItem cache = makeSure(groupKey, null); - cache.initBetaCacheIfEmpty(); - String betaMd5Utf8 = cache.getConfigCacheBeta().getMd5(ENCODE_UTF8); - if (betaMd5Utf8 == null || !betaMd5Utf8.equals(md5Utf8) || !CollectionUtils.isListEqual(ips4Beta, - cache.ips4Beta)) { - cache.isBeta = true; - cache.ips4Beta = ips4Beta; - cache.getConfigCacheBeta().setMd5Utf8(md5Utf8); - cache.getConfigCacheBeta().setLastModifiedTs(lastModifiedTs); - cache.getConfigCacheBeta().setEncryptedDataKey(encryptedDataKey4Beta); - NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, ips4Beta)); - } - } - - /** - * Update tag md5 value. - * - * @param groupKey groupKey string value. - * @param tag tag string value. - * @param md5Utf8 md5UTF8 string value. - * @param lastModifiedTs lastModifiedTs long value. - */ - public static void updateTagMd5(String groupKey, String tag, String md5Utf8, long lastModifiedTs, - String encryptedDataKey4Tag) { - CacheItem cache = makeSure(groupKey, null); - cache.initConfigTagsIfEmpty(tag); - ConfigCache configCache = cache.getConfigCacheTags().get(tag); + cache.initConfigGrayIfEmpty(grayName); + ConfigCacheGray configCache = cache.getConfigCacheGray().get(grayName); configCache.setMd5Utf8(md5Utf8); configCache.setLastModifiedTs(lastModifiedTs); - configCache.setEncryptedDataKey(encryptedDataKey4Tag); - NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, tag)); + configCache.setEncryptedDataKey(encryptedDataKey); + configCache.resetGrayRule(grayRule); + cache.sortConfigGray(); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); } /** * Get and return content md5 value from cache. Empty string represents no data. */ public static String getContentMd5(String groupKey) { - return getContentMd5(groupKey, "", ""); + return getContentMd5(groupKey, null, null); } public static String getContentMd5(String groupKey, String ip, String tag) { + return getContentMd5(groupKey, ip, tag, null, ENCODE_UTF8); + } + + public static String getContentMd5(String groupKey, String ip, String tag, Map connLabels, + String encode) { CacheItem item = CACHE.get(groupKey); - if (item != null && item.isBeta && item.ips4Beta != null && item.ips4Beta.contains(ip) - && item.getConfigCacheBeta() != null) { - return item.getConfigCacheBeta().getMd5(ENCODE_UTF8); + if (item == null) { + return NULL; } - - if (item != null && StringUtils.isNotBlank(tag) && item.getConfigCacheTags() != null - && item.getConfigCacheTags().containsKey(tag)) { - return item.getConfigCacheTags().get(tag).getMd5(ENCODE_UTF8); + if (connLabels == null && StringUtils.isNotBlank(ip)) { + connLabels = new HashMap<>(4); } - - if (item != null && item.isBatch && item.delimiter >= InternetAddressUtil.ipToInt(ip) - && item.getConfigCacheBatch() != null) { - return item.getConfigCacheBatch().getMd5(ENCODE_UTF8); + if (connLabels == null && StringUtils.isNotBlank(tag)) { + connLabels = new HashMap<>(4); } - return (null != item) ? item.getConfigCache().getMd5(ENCODE_UTF8) : Constants.NULL; + if (StringUtils.isNotBlank(ip)) { + connLabels.put(CLIENT_IP, ip); + } + if (StringUtils.isNotBlank(tag)) { + connLabels.put(VIPSERVER_TAG, tag); + } + if (item.getSortConfigGrays() != null && connLabels != null && !connLabels.isEmpty()) { + for (ConfigCacheGray entry : item.getSortConfigGrays()) { + if (entry.match(connLabels)) { + return entry.getMd5(encode); + } + } + } + String md5 = item.getConfigCache().getMd5(encode); + return md5 == null ? NULL : md5; } - /** - * Get and return beta md5 value from cache. Empty string represents no data. - */ - public static String getContentBetaMd5(String groupKey) { - CacheItem item = CACHE.get(groupKey); - - if (item == null || item.getConfigCacheBeta() == null) { - return Constants.NULL; - } - return item.getConfigCacheBeta().getMd5(ENCODE_UTF8); + private static void updateGrayRule(String groupKey, String grayName, String grayRule, long lastModifiedTs, + String encryptedDataKey) { + CacheItem cache = makeSure(groupKey, null); + cache.initConfigGrayIfEmpty(grayName); + ConfigCacheGray configCache = cache.getConfigCacheGray().get(grayName); + configCache.setLastModifiedTs(lastModifiedTs); + configCache.setEncryptedDataKey(encryptedDataKey); + configCache.resetGrayRule(grayRule); + cache.sortConfigGray(); + NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey)); } /** - * Get and return tag md5 value from cache. Empty string represents no data. + * Get and return gray md5 value from cache. Empty string represents no data. * * @param groupKey groupKey string value. - * @param tag tag string value. + * @param grayName grayName string value. * @return Content Tag Md5 value. */ - public static String getContentTagMd5(String groupKey, String tag) { + public static String getContentGrayMd5(String groupKey, String grayName) { CacheItem item = CACHE.get(groupKey); - if (item == null || item.getConfigCacheTags() == null || !item.getConfigCacheTags().containsKey(tag)) { - return Constants.NULL; + if (item == null || item.getConfigCacheGray() == null || !item.getConfigCacheGray().containsKey(grayName)) { + return NULL; } - return item.getConfigCacheTags().get(tag).getMd5(ENCODE_UTF8); + return item.getConfigCacheGray().get(grayName).getMd5(ENCODE_UTF8); } - /** - * Get and return beta ip list. - * - * @param groupKey groupKey string value. - * @return list beta ips. - */ - public static List getBetaIps(String groupKey) { + public static long getGrayLastModifiedTs(String groupKey, String grayName) { CacheItem item = CACHE.get(groupKey); - return (null != item) ? item.getIps4Beta() : Collections.emptyList(); - } - - public static long getBetaLastModifiedTs(String groupKey) { - CacheItem item = CACHE.get(groupKey); - return (null != item && item.getConfigCacheBeta() != null) ? item.getConfigCacheBeta().getLastModifiedTs() : 0L; + if (item.getConfigCacheGray() == null || !item.getConfigCacheGray().containsKey(grayName)) { + return 0; + } + ConfigCache configCacheGray = item.getConfigCacheGray().get(grayName); + + return (null != configCacheGray) ? configCacheGray.getLastModifiedTs() : 0; } - public static long getTagLastModifiedTs(String groupKey, String tag) { + public static GrayRule getGrayRule(String groupKey, String grayName) { CacheItem item = CACHE.get(groupKey); - if (item.getConfigCacheTags() == null || !item.getConfigCacheTags().containsKey(tag)) { - return 0; + if (item == null || item.getConfigCacheGray() == null || !item.getConfigCacheGray().containsKey(grayName)) { + return null; } - ConfigCache configCacheTag = item.getConfigCacheTags().get(tag); - - return (null != configCacheTag) ? configCacheTag.getLastModifiedTs() : 0; + return item.getConfigCacheGray().get(grayName).getGrayRule(); } /** @@ -596,26 +482,29 @@ public static long getLastModifiedTs(String groupKey) { } /** - * update tag timestamp. + * update gray timestamp. * * @param groupKey groupKey. - * @param tag tag. + * @param grayName grayName. * @param lastModifiedTs lastModifiedTs. */ - public static void updateTagTimeStamp(String groupKey, String tag, long lastModifiedTs) { + private static void updateGrayTimeStamp(String groupKey, String grayName, long lastModifiedTs) { CacheItem cache = makeSure(groupKey, null); - cache.initConfigTagsIfEmpty(tag); - cache.getConfigCacheTags().get(tag).setLastModifiedTs(lastModifiedTs); - + cache.initConfigGrayIfEmpty(grayName); + cache.getConfigCacheGray().get(grayName).setLastModifiedTs(lastModifiedTs); } public static boolean isUptodate(String groupKey, String md5) { - String serverMd5 = ConfigCacheService.getContentMd5(groupKey); - return StringUtils.equals(md5, serverMd5); + return isUptodate(groupKey, md5, null, null); } public static boolean isUptodate(String groupKey, String md5, String ip, String tag) { - String serverMd5 = ConfigCacheService.getContentMd5(groupKey, ip, tag); + return isUptodate(groupKey, md5, ip, tag, null); + } + + public static boolean isUptodate(String groupKey, String md5, String ip, String tag, + Map appLabels) { + String serverMd5 = ConfigCacheService.getContentMd5(groupKey, ip, tag, appLabels, ENCODE_UTF8); return StringUtils.equals(md5, serverMd5); } @@ -687,41 +576,11 @@ static CacheItem makeSure(final String groupKey, final String encryptedDataKey) * @param lastModifiedTs lastModifiedTs. * @param encryptedDataKey encryptedDataKey. */ - public static void updateTimeStamp(String groupKey, long lastModifiedTs, String encryptedDataKey) { + private static void updateTimeStamp(String groupKey, long lastModifiedTs, String encryptedDataKey) { CacheItem cache = makeSure(groupKey, encryptedDataKey); cache.getConfigCache().setLastModifiedTs(lastModifiedTs); } - /** - * update beta ip list. - * - * @param groupKey groupKey. - * @param ips4Beta ips4Beta. - * @param lastModifiedTs lastModifiedTs. - */ - private static void updateBetaIpList(String groupKey, List ips4Beta, long lastModifiedTs) { - CacheItem cache = makeSure(groupKey, null); - cache.initBetaCacheIfEmpty(); - cache.setBeta(true); - cache.setIps4Beta(ips4Beta); - cache.getConfigCacheBeta().setLastModifiedTs(lastModifiedTs); - NotifyCenter.publishEvent(new LocalDataChangeEvent(groupKey, true, ips4Beta)); - - } - - /** - * update beta lastModifiedTs. - * - * @param groupKey groupKey. - * @param lastModifiedTs lastModifiedTs. - */ - private static void updateBetaTimeStamp(String groupKey, long lastModifiedTs) { - CacheItem cache = makeSure(groupKey, null); - cache.initBetaCacheIfEmpty(); - cache.getConfigCacheBeta().setLastModifiedTs(lastModifiedTs); - - } - private static final int TRY_GET_LOCK_TIMES = 9; /** diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigGrayModelMigrateService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigGrayModelMigrateService.java new file mode 100644 index 00000000000..e6e3ffdfb25 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigGrayModelMigrateService.java @@ -0,0 +1,177 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service; + +import com.alibaba.nacos.api.utils.NetUtils; +import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.ConfigGrayPersistInfo; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; +import com.alibaba.nacos.persistence.model.Page; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; + +import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; + +/** + * config gray model migrate.migrate beta and tag to gray model. + * + * @author shiyiyue + */ +@Service +public class ConfigGrayModelMigrateService { + + ConfigInfoBetaPersistService configInfoBetaPersistService; + + ConfigInfoTagPersistService configInfoTagPersistService; + + ConfigInfoGrayPersistService configInfoGrayPersistService; + + public ConfigGrayModelMigrateService(ConfigInfoBetaPersistService configInfoBetaPersistService, + ConfigInfoTagPersistService configInfoTagPersistService, + ConfigInfoGrayPersistService configInfoGrayPersistService) { + this.configInfoBetaPersistService = configInfoBetaPersistService; + this.configInfoGrayPersistService = configInfoGrayPersistService; + this.configInfoTagPersistService = configInfoTagPersistService; + } + + /** + * migrate beta&tag to gray . + */ + @PostConstruct + public void migrate() { + doCheckMigrate(); + } + + /** + * migrate single config beta. + * + * @param dataId dataId. + * @param group group. + * @param tenant tenant. + */ + public void checkMigrateBeta(String dataId, String group, String tenant) { + ConfigInfoBetaWrapper configInfo4Beta = configInfoBetaPersistService.findConfigInfo4Beta(dataId, group, tenant); + if (configInfo4Beta == null) { + return; + } + ConfigInfoGrayWrapper configInfo4Gray = configInfoGrayPersistService.findConfigInfo4Gray(dataId, group, tenant, + BetaGrayRule.TYPE_BETA); + if (configInfo4Gray == null || configInfo4Gray.getLastModified() < configInfo4Beta.getLastModified()) { + DEFAULT_LOG.info("[migrate beta to gray] dataId={}, group={}, tenant={}, md5={}", + configInfo4Beta.getDataId(), configInfo4Beta.getGroup(), configInfo4Beta.getTenant(), + configInfo4Beta.getMd5()); + ConfigGrayPersistInfo localConfigGrayPersistInfo = new ConfigGrayPersistInfo(BetaGrayRule.TYPE_BETA, + BetaGrayRule.VERSION, configInfo4Beta.getBetaIps(), BetaGrayRule.PROPRITY); + configInfoGrayPersistService.insertOrUpdateGray(configInfo4Beta, BetaGrayRule.TYPE_BETA, + GrayRuleManager.serializeConfigGrayPersistInfo(localConfigGrayPersistInfo), NetUtils.localIP(), + "nacos_auto_migrate"); + } + + } + + /** + * migrate single config tag. + * + * @param dataId dataId. + * @param group group. + * @param tenant tenant. + * @param tag tag. + */ + public void checkMigrateTag(String dataId, String group, String tenant, String tag) { + ConfigInfoTagWrapper configInfo4Tag = configInfoTagPersistService.findConfigInfo4Tag(dataId, group, tenant, + tag); + if (configInfo4Tag == null) { + return; + } + ConfigInfoGrayWrapper configInfo4Gray = configInfoGrayPersistService.findConfigInfo4Gray(dataId, group, tenant, + TagGrayRule.TYPE_TAG + "_" + tag); + if (configInfo4Gray == null || configInfo4Gray.getLastModified() < configInfo4Tag.getLastModified()) { + DEFAULT_LOG.info("[migrate tag to gray] dataId={}, group={}, tenant={}, md5={}", + configInfo4Tag.getDataId(), configInfo4Tag.getGroup(), configInfo4Tag.getTenant(), + configInfo4Tag.getMd5()); + ConfigGrayPersistInfo localConfigGrayPersistInfo = new ConfigGrayPersistInfo(TagGrayRule.TYPE_TAG, + TagGrayRule.VERSION, configInfo4Tag.getTag(), TagGrayRule.PROPRITY); + configInfoGrayPersistService.insertOrUpdateGray(configInfo4Tag, TagGrayRule.TYPE_TAG, + GrayRuleManager.serializeConfigGrayPersistInfo(localConfigGrayPersistInfo), NetUtils.localIP(), + "nacos_auto_migrate"); + } + } + + private void doCheckMigrate() { + int pageSize = 100; + int rowCount = configInfoBetaPersistService.configInfoBetaCount(); + int pageCount = (int) Math.ceil(rowCount * 1.0 / pageSize); + int actualRowCount = 0; + for (int pageNo = 1; pageNo <= pageCount; pageNo++) { + Page page = configInfoBetaPersistService.findAllConfigInfoBetaForDumpAll(pageNo, + pageSize); + if (page != null) { + for (ConfigInfoBetaWrapper cf : page.getPageItems()) { + + ConfigInfoGrayWrapper configInfo4Gray = configInfoGrayPersistService.findConfigInfo4Gray( + cf.getDataId(), cf.getGroup(), cf.getTenant(), BetaGrayRule.TYPE_BETA); + if (configInfo4Gray == null || configInfo4Gray.getLastModified() < cf.getLastModified()) { + DEFAULT_LOG.info("[migrate beta to gray] dataId={}, group={}, tenant={}, md5={}", + cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getMd5()); + ConfigGrayPersistInfo localConfigGrayPersistInfo = new ConfigGrayPersistInfo( + BetaGrayRule.TYPE_BETA, BetaGrayRule.VERSION, cf.getBetaIps(), BetaGrayRule.PROPRITY); + configInfoGrayPersistService.insertOrUpdateGray(cf, BetaGrayRule.TYPE_BETA, + GrayRuleManager.serializeConfigGrayPersistInfo(localConfigGrayPersistInfo), + NetUtils.localIP(), "nacos_auto_migrate"); + } + + } + actualRowCount += page.getPageItems().size(); + } + } + + rowCount = configInfoBetaPersistService.configInfoBetaCount(); + pageCount = (int) Math.ceil(rowCount * 1.0 / pageSize); + actualRowCount = 0; + for (int pageNo = 1; pageNo <= pageCount; pageNo++) { + Page page = configInfoTagPersistService.findAllConfigInfoTagForDumpAll(pageNo, + pageSize); + if (page != null) { + for (ConfigInfoTagWrapper cf : page.getPageItems()) { + ConfigInfoGrayWrapper configInfo4Gray = configInfoGrayPersistService.findConfigInfo4Gray( + cf.getDataId(), cf.getGroup(), cf.getTenant(), TagGrayRule.TYPE_TAG + "_" + cf.getTag()); + if (configInfo4Gray == null || configInfo4Gray.getLastModified() < cf.getLastModified()) { + DEFAULT_LOG.info("[migrate tag to gray] dataId={}, group={}, tenant={}, md5={}", + cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getMd5()); + ConfigGrayPersistInfo localConfigGrayPersistInfo = new ConfigGrayPersistInfo( + TagGrayRule.TYPE_TAG, TagGrayRule.VERSION, cf.getTag(), TagGrayRule.PROPRITY); + configInfoGrayPersistService.insertOrUpdateGray(cf, TagGrayRule.TYPE_TAG + "_" + cf.getTag(), + GrayRuleManager.serializeConfigGrayPersistInfo(localConfigGrayPersistInfo), + NetUtils.localIP(), "nacos_auto_migrate"); + } + } + + actualRowCount += page.getPageItems().size(); + DEFAULT_LOG.info("[-tag] {} / {}", actualRowCount, rowCount); + } + } + } + +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java index 9a1ea51991e..f21e6fbaadb 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java @@ -20,18 +20,27 @@ import com.alibaba.nacos.api.exception.api.NacosApiException; import com.alibaba.nacos.api.model.v2.ErrorCode; import com.alibaba.nacos.common.utils.MapUtil; +import com.alibaba.nacos.common.utils.NumberUtils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.model.ConfigRequestInfo; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.model.form.ConfigForm; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.ConfigGrayPersistInfo; +import com.alibaba.nacos.config.server.model.gray.GrayRule; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.service.trace.ConfigTraceService; import com.alibaba.nacos.config.server.utils.ParamUtils; +import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.config.server.utils.TimeUtils; +import com.alibaba.nacos.sys.env.EnvUtil; import com.alibaba.nacos.sys.utils.InetUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,6 +49,7 @@ import java.sql.Timestamp; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -58,14 +68,18 @@ public class ConfigOperationService { private ConfigInfoBetaPersistService configInfoBetaPersistService; + private ConfigInfoGrayPersistService configInfoGrayPersistService; + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigOperationService.class); public ConfigOperationService(ConfigInfoPersistService configInfoPersistService, ConfigInfoTagPersistService configInfoTagPersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService) { + ConfigInfoBetaPersistService configInfoBetaPersistService, + ConfigInfoGrayPersistService configInfoGrayPersistService) { this.configInfoPersistService = configInfoPersistService; this.configInfoTagPersistService = configInfoTagPersistService; this.configInfoBetaPersistService = configInfoBetaPersistService; + this.configInfoGrayPersistService = configInfoGrayPersistService; } /** @@ -85,7 +99,7 @@ public Boolean publishConfig(ConfigForm configForm, ConfigRequestInfo configRequ throw new NacosApiException(HttpStatus.FORBIDDEN.value(), ErrorCode.INVALID_DATA_ID, "dataId:" + configForm.getDataId() + " is aggr"); } - + configForm.setEncryptedDataKey(encryptedDataKey); ConfigInfo configInfo = new ConfigInfo(configForm.getDataId(), configForm.getGroup(), configForm.getNamespaceId(), configForm.getAppName(), configForm.getContent()); //set old md5 @@ -96,97 +110,227 @@ public Boolean publishConfig(ConfigForm configForm, ConfigRequestInfo configRequ configInfo.setEncryptedDataKey(encryptedDataKey); ConfigOperateResult configOperateResult; - String persistEvent = ConfigTraceService.PERSISTENCE_EVENT; + //beta public + if (StringUtils.isNotBlank(configRequestInfo.getBetaIps())) { + configForm.setGrayName(BetaGrayRule.TYPE_BETA); + configForm.setGrayRuleExp(configRequestInfo.getBetaIps()); + configForm.setGrayVersion(BetaGrayRule.VERSION); + persistBeta(configForm, configInfo, configRequestInfo); + publishConfigGray(BetaGrayRule.TYPE_BETA, configForm, configRequestInfo); + return Boolean.TRUE; + } + // tag publish + if (StringUtils.isNotBlank(configForm.getTag())) { + configForm.setGrayName(TagGrayRule.TYPE_TAG + "_" + configForm.getTag()); + configForm.setGrayRuleExp(configForm.getTag()); + configForm.setGrayVersion(TagGrayRule.VERSION); + persistTagv1(configForm, configInfo, configRequestInfo); + publishConfigGray(TagGrayRule.TYPE_TAG, configForm, configRequestInfo); + return Boolean.TRUE; + } - if (StringUtils.isBlank(configRequestInfo.getBetaIps())) { - if (StringUtils.isBlank(configForm.getTag())) { - if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { - configOperateResult = configInfoPersistService.insertOrUpdateCas(configRequestInfo.getSrcIp(), - configForm.getSrcUser(), configInfo, configAdvanceInfo); - if (!configOperateResult.isSuccess()) { - LOGGER.warn( - "[cas-publish-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, msg = server md5 may have changed.", - configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5()); - throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), - ErrorCode.RESOURCE_CONFLICT, "Cas publish fail, server md5 may have changed."); - } - } else { - configOperateResult = configInfoPersistService.insertOrUpdate(configRequestInfo.getSrcIp(), - configForm.getSrcUser(), configInfo, configAdvanceInfo); - } - ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(false, configForm.getDataId(), configForm.getGroup(), - configForm.getNamespaceId(), configOperateResult.getLastModified())); - } else { - if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { - configOperateResult = configInfoTagPersistService.insertOrUpdateTagCas(configInfo, - configForm.getTag(), configRequestInfo.getSrcIp(), configForm.getSrcUser()); - if (!configOperateResult.isSuccess()) { - LOGGER.warn( - "[cas-publish-tag-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, msg = server md5 may have changed.", - configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5()); - throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), - ErrorCode.RESOURCE_CONFLICT, - "Cas publish tag config fail, server md5 may have changed."); - } - } else { - configOperateResult = configInfoTagPersistService.insertOrUpdateTag(configInfo, configForm.getTag(), - configRequestInfo.getSrcIp(), configForm.getSrcUser()); - } - persistEvent = ConfigTraceService.PERSISTENCE_EVENT_TAG + "-" + configForm.getTag(); - ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(false, configForm.getDataId(), configForm.getGroup(), - configForm.getNamespaceId(), configForm.getTag(), - configOperateResult.getLastModified())); + //formal publish + if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { + configOperateResult = configInfoPersistService.insertOrUpdateCas(configRequestInfo.getSrcIp(), + configForm.getSrcUser(), configInfo, configAdvanceInfo); + if (!configOperateResult.isSuccess()) { + LOGGER.warn( + "[cas-publish-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, msg = server md5 may have changed.", + configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5()); + throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.RESOURCE_CONFLICT, + "Cas publish fail, server md5 may have changed."); } } else { - // beta publish - if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { - configOperateResult = configInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, - configRequestInfo.getBetaIps(), configRequestInfo.getSrcIp(), configForm.getSrcUser()); - if (!configOperateResult.isSuccess()) { - LOGGER.warn( - "[cas-publish-beta-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, msg = server md5 may have changed.", - configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5()); - throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.RESOURCE_CONFLICT, - "Cas publish beta config fail, server md5 may have changed."); - } - } else { - configOperateResult = configInfoBetaPersistService.insertOrUpdateBeta(configInfo, - configRequestInfo.getBetaIps(), configRequestInfo.getSrcIp(), configForm.getSrcUser()); + configOperateResult = configInfoPersistService.insertOrUpdate(configRequestInfo.getSrcIp(), + configForm.getSrcUser(), configInfo, configAdvanceInfo); + } + ConfigChangePublisher.notifyConfigChange( + new ConfigDataChangeEvent(false, configForm.getDataId(), configForm.getGroup(), + configForm.getNamespaceId(), configOperateResult.getLastModified())); + ConfigTraceService.logPersistenceEvent(configForm.getDataId(), configForm.getGroup(), + configForm.getNamespaceId(), configRequestInfo.getRequestIpApp(), configOperateResult.getLastModified(), + InetUtils.getSelfIP(), ConfigTraceService.PERSISTENCE_EVENT, ConfigTraceService.PERSISTENCE_TYPE_PUB, + configForm.getContent()); + return true; + } + + private void persistTagv1(ConfigForm configForm, ConfigInfo configInfo, ConfigRequestInfo configRequestInfo) + throws NacosApiException { + if (!PropertyUtil.isGrayCompatibleModel()) { + return; + } + + ConfigOperateResult configOperateResult = null; + if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { + configOperateResult = configInfoTagPersistService.insertOrUpdateTagCas(configInfo, configForm.getTag(), + configRequestInfo.getSrcIp(), configForm.getSrcUser()); + if (!configOperateResult.isSuccess()) { + LOGGER.warn( + "[cas-publish-tag-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, msg = server md5 may have changed.", + configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5()); + throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.RESOURCE_CONFLICT, + "Cas publish tag config fail, server md5 may have changed."); } - persistEvent = ConfigTraceService.PERSISTENCE_EVENT_BETA; - ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(true, configForm.getDataId(), configForm.getGroup(), - configForm.getNamespaceId(), configOperateResult.getLastModified())); + } else { + configOperateResult = configInfoTagPersistService.insertOrUpdateTag(configInfo, configForm.getTag(), + configRequestInfo.getSrcIp(), configForm.getSrcUser()); } + ConfigChangePublisher.notifyConfigChange( + new ConfigDataChangeEvent(false, configForm.getDataId(), configForm.getGroup(), + configForm.getNamespaceId(), configForm.getTag(), configOperateResult.getLastModified())); + } + + private void persistBeta(ConfigForm configForm, ConfigInfo configInfo, ConfigRequestInfo configRequestInfo) + throws NacosApiException { + if (!PropertyUtil.isGrayCompatibleModel()) { + return; + } + ConfigOperateResult configOperateResult = null; + // beta publish + if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { + configOperateResult = configInfoBetaPersistService.insertOrUpdateBetaCas(configInfo, + configRequestInfo.getBetaIps(), configRequestInfo.getSrcIp(), configForm.getSrcUser()); + if (!configOperateResult.isSuccess()) { + LOGGER.warn( + "[cas-publish-beta-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, msg = server md5 may have changed.", + configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5()); + throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.RESOURCE_CONFLICT, + "Cas publish beta config fail, server md5 may have changed."); + } + } else { + configOperateResult = configInfoBetaPersistService.insertOrUpdateBeta(configInfo, + configRequestInfo.getBetaIps(), configRequestInfo.getSrcIp(), configForm.getSrcUser()); + } + ConfigChangePublisher.notifyConfigChange( + new ConfigDataChangeEvent(true, configForm.getDataId(), configForm.getGroup(), + configForm.getNamespaceId(), configOperateResult.getLastModified())); + } + + /** + * publish gray config tag v2. + * + * @param configForm ConfigForm + * @param configRequestInfo ConfigRequestInfo + * @return boolean + * @throws NacosException NacosException. + * @date 2024/2/5 + */ + private Boolean publishConfigGray(String grayType, ConfigForm configForm, ConfigRequestInfo configRequestInfo) + throws NacosException { + + Map configAdvanceInfo = getConfigAdvanceInfo(configForm); + ParamUtils.checkParam(configAdvanceInfo); + + ConfigGrayPersistInfo localConfigGrayPersistInfo = new ConfigGrayPersistInfo(grayType, + configForm.getGrayVersion(), configForm.getGrayRuleExp(), configForm.getGrayPriority()); + GrayRule grayRuleStruct = GrayRuleManager.constructGrayRule(localConfigGrayPersistInfo); + if (grayRuleStruct == null) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.CONFIG_GRAY_VERSION_INVALID, + ErrorCode.CONFIG_GRAY_VERSION_INVALID.getMsg()); + } + + if (!grayRuleStruct.isValid()) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.CONFIG_GRAY_RULE_FORMAT_INVALID, + ErrorCode.CONFIG_GRAY_RULE_FORMAT_INVALID.getMsg()); + } + + //version count check. + if (checkGrayVersionOverMaxCount(configForm.getDataId(), configForm.getGroup(), configForm.getNamespaceId(), + configForm.getGrayName())) { + throw new NacosApiException(HttpStatus.BAD_REQUEST.value(), ErrorCode.CONFIG_GRAY_OVER_MAX_VERSION_COUNT, + "gray config version is over max count :" + getMaxGrayVersionCount()); + } + + ConfigInfo configInfo = new ConfigInfo(configForm.getDataId(), configForm.getGroup(), + configForm.getNamespaceId(), configForm.getAppName(), configForm.getContent()); + configInfo.setType(configForm.getType()); + configInfo.setEncryptedDataKey(configForm.getEncryptedDataKey()); + + ConfigOperateResult configOperateResult; + + if (StringUtils.isNotBlank(configRequestInfo.getCasMd5())) { + configOperateResult = configInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, + configForm.getGrayName(), + GrayRuleManager.serializeConfigGrayPersistInfo(localConfigGrayPersistInfo), + configRequestInfo.getSrcIp(), configForm.getSrcUser()); + if (!configOperateResult.isSuccess()) { + LOGGER.warn( + "[cas-publish-gray-config-fail] srcIp = {}, dataId= {}, casMd5 = {}, grayName = {}, msg = server md5 may have changed.", + configRequestInfo.getSrcIp(), configForm.getDataId(), configRequestInfo.getCasMd5(), + configForm.getGrayName()); + throw new NacosApiException(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCode.RESOURCE_CONFLICT, + "Cas publish gray config fail, server md5 may have changed."); + } + } else { + configOperateResult = configInfoGrayPersistService.insertOrUpdateGray(configInfo, configForm.getGrayName(), + GrayRuleManager.serializeConfigGrayPersistInfo(localConfigGrayPersistInfo), + configRequestInfo.getSrcIp(), configForm.getSrcUser()); + } + + ConfigChangePublisher.notifyConfigChange( + new ConfigDataChangeEvent(configForm.getDataId(), configForm.getGroup(), configForm.getNamespaceId(), + null, configForm.getGrayName(), configOperateResult.getLastModified())); + + String eventType = ConfigTraceService.PERSISTENCE_EVENT + "-" + configForm.getGrayName(); + ConfigTraceService.logPersistenceEvent(configForm.getDataId(), configForm.getGroup(), configForm.getNamespaceId(), configRequestInfo.getRequestIpApp(), configOperateResult.getLastModified(), - InetUtils.getSelfIP(), persistEvent, ConfigTraceService.PERSISTENCE_TYPE_PUB, configForm.getContent()); + InetUtils.getSelfIP(), eventType, ConfigTraceService.PERSISTENCE_TYPE_PUB, configForm.getContent()); return true; } + private boolean checkGrayVersionOverMaxCount(String dataId, String group, String tenant, String grayName) { + List configInfoGrays = configInfoGrayPersistService.findConfigInfoGrays(dataId, group, tenant); + if (configInfoGrays == null || configInfoGrays.isEmpty()) { + return false; + } else { + if (configInfoGrays.contains(grayName)) { + return false; + } + return configInfoGrays.size() >= getMaxGrayVersionCount(); + } + } + + private static final int DEFAULT_MAX_GRAY_VERSION_COUNT = 10; + + private int getMaxGrayVersionCount() { + String value = EnvUtil.getProperty("nacos.config.gray.version.max.count", ""); + return NumberUtils.isDigits(value) ? NumberUtils.toInt(value) : DEFAULT_MAX_GRAY_VERSION_COUNT; + } + /** * Synchronously delete all pre-aggregation data under a dataId. */ public Boolean deleteConfig(String dataId, String group, String namespaceId, String tag, String clientIp, String srcUser) { String persistEvent = ConfigTraceService.PERSISTENCE_EVENT; + String grayName = ""; if (StringUtils.isBlank(tag)) { configInfoPersistService.removeConfigInfo(dataId, group, namespaceId, clientIp, srcUser); } else { persistEvent = ConfigTraceService.PERSISTENCE_EVENT_TAG + "-" + tag; - configInfoTagPersistService.removeConfigInfoTag(dataId, group, namespaceId, tag, clientIp, srcUser); + grayName = TagGrayRule.TYPE_TAG + "_" + tag; + configInfoGrayPersistService.removeConfigInfoGray(dataId, group, namespaceId, grayName, clientIp, srcUser); + deleteConfigTagv1(dataId, group, namespaceId, tag, clientIp, srcUser); } final Timestamp time = TimeUtils.getCurrentTime(); ConfigTraceService.logPersistenceEvent(dataId, group, namespaceId, null, time.getTime(), clientIp, persistEvent, ConfigTraceService.PERSISTENCE_TYPE_REMOVE, null); ConfigChangePublisher.notifyConfigChange( - new ConfigDataChangeEvent(false, dataId, group, namespaceId, tag, time.getTime())); + new ConfigDataChangeEvent(dataId, group, namespaceId, null, grayName, time.getTime())); return true; } + private void deleteConfigTagv1(String dataId, String group, String namespaceId, String tag, String clientIp, + String srcUser) { + if (PropertyUtil.isGrayCompatibleModel()) { + configInfoTagPersistService.removeConfigInfoTag(dataId, group, namespaceId, tag, clientIp, srcUser); + ConfigChangePublisher.notifyConfigChange( + new ConfigDataChangeEvent(false, dataId, group, namespaceId, tag, System.currentTimeMillis())); + } + } + public Map getConfigAdvanceInfo(ConfigForm configForm) { Map configAdvanceInfo = new HashMap<>(10); MapUtil.putIfValNoNull(configAdvanceInfo, "config_tags", configForm.getConfigTags()); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java index ebf7afabb1a..1a2d3f42bce 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigSubService.java @@ -160,12 +160,13 @@ public T call() throws Exception { List runJobs() { Collection ipList = serverMemberManager.allMembers(); List collectionResult = new ArrayList<>(ipList.size()); + // Submit query task. for (Member ip : ipList) { try { completionService.submit(new Job(ip.getAddress()) { }); - } catch (Exception e) { // Send request failed. + } catch (Throwable e) { // Send request failed. LogUtil.DEFAULT_LOG.warn("invoke to {} with exception: {} during submit job", ip, e.getMessage()); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java index d79b34cd421..ab571ca02ff 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/LongPollingService.java @@ -21,7 +21,6 @@ import com.alibaba.nacos.common.notify.NotifyCenter; import com.alibaba.nacos.common.notify.listener.Subscriber; import com.alibaba.nacos.common.utils.ExceptionUtil; -import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.model.SampleResult; import com.alibaba.nacos.config.server.model.event.LocalDataChangeEvent; import com.alibaba.nacos.config.server.monitor.MetricsMonitor; @@ -243,7 +242,7 @@ public LongPollingService() { public void onEvent(Event event) { if (event instanceof LocalDataChangeEvent) { LocalDataChangeEvent evt = (LocalDataChangeEvent) event; - ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps)); + ConfigExecutor.executeLongPolling(new DataChangeTask(evt.groupKey)); } } @@ -274,11 +273,6 @@ public void run() { ClientLongPolling clientSub = iter.next(); if (clientSub.clientMd5Map.containsKey(groupKey)) { - // If published tag is not in the tag list, then it skipped. - if (StringUtils.isNotBlank(tag) && !tag.equals(clientSub.tag)) { - continue; - } - getRetainIps().put(clientSub.ip, System.currentTimeMillis()); iter.remove(); // Delete subscribers' relationships. LogUtil.CLIENT_LOG.info("{}|{}|{}|{}|{}|{}|{}", (System.currentTimeMillis() - changeTime), @@ -294,26 +288,14 @@ public void run() { } } - DataChangeTask(String groupKey, boolean isBeta, List betaIps) { - this(groupKey, isBeta, betaIps, null); - } - - DataChangeTask(String groupKey, boolean isBeta, List betaIps, String tag) { + DataChangeTask(String groupKey) { this.groupKey = groupKey; - this.isBeta = isBeta; - this.betaIps = betaIps; - this.tag = tag; } final String groupKey; final long changeTime = System.currentTimeMillis(); - final boolean isBeta; - - final List betaIps; - - final String tag; } class StatTask implements Runnable { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java new file mode 100644 index 00000000000..ebb42754631 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java @@ -0,0 +1,114 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.dump; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.service.ConfigCacheService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; +import com.alibaba.nacos.config.server.utils.GroupKey2; +import com.alibaba.nacos.config.server.utils.LogUtil; +import com.alibaba.nacos.config.server.utils.PropertyUtil; + +import java.sql.Timestamp; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * Dump gray config worker. + * + * @author shiyiyue + */ +public class DumpChangeGrayConfigWorker implements Runnable { + + Timestamp startTime; + + ConfigInfoGrayPersistService configInfoGrayPersistService; + + int pageSize = 100; + + public DumpChangeGrayConfigWorker(ConfigInfoGrayPersistService configInfoGrayPersistService, Timestamp startTime) { + this.configInfoGrayPersistService = configInfoGrayPersistService; + this.startTime = startTime; + } + + @Override + public void run() { + try { + + if (!PropertyUtil.isDumpChangeOn()) { + LogUtil.DEFAULT_LOG.info("DumpGrayChange task is not open"); + return; + } + Timestamp currentTime = new Timestamp(System.currentTimeMillis()); + LogUtil.DEFAULT_LOG.info("DumpGrayChange start ,from time {},current time {}", startTime, currentTime); + + LogUtil.DEFAULT_LOG.info("Check changeGrayConfig start"); + long startChangeConfigTime = System.currentTimeMillis(); + + long changeCursorId = 0L; + while (true) { + LogUtil.DEFAULT_LOG.info("Check changed gray configs from time {},lastMaxId={}", startTime, + changeCursorId); + List changeConfigs = configInfoGrayPersistService.findChangeConfig(startTime, + changeCursorId, pageSize); + for (ConfigInfoGrayWrapper cf : changeConfigs) { + final String groupKey = GroupKey2.getKey(cf.getDataId(), cf.getGroup(), cf.getTenant()); + //check md5 & localtimestamp update local disk cache. + boolean newLastModified = cf.getLastModified() > ConfigCacheService.getLastModifiedTs(groupKey); + String localContentMd5 = ConfigCacheService.getContentMd5(groupKey); + boolean md5Update = !localContentMd5.equals(cf.getMd5()); + if (newLastModified || md5Update) { + LogUtil.DEFAULT_LOG.info("[dump-change-gray] find change config {}, {}, md5={}", + new Object[] {groupKey, cf.getLastModified(), cf.getMd5()}); + + LogUtil.DUMP_LOG.info("[dump-change-gray] find change config {}, {}, md5={}", + new Object[] {groupKey, cf.getLastModified(), cf.getMd5()}); + ConfigCacheService.dumpGray(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getGrayName(), + cf.getGrayRule(), cf.getContent(), cf.getLastModified(), cf.getEncryptedDataKey()); + final String content = cf.getContent(); + final String md5 = MD5Utils.md5Hex(content, Constants.ENCODE_GBK); + final String md5Utf8 = MD5Utils.md5Hex(content, Constants.ENCODE_UTF8); + + LogUtil.DEFAULT_LOG.info("[dump-change-gray-ok] {}, {}, length={}, md5={},md5UTF8={}", + new Object[] {groupKey, cf.getLastModified(), content.length(), md5, md5Utf8}); + } + } + if (changeConfigs.size() < pageSize) { + break; + } + changeCursorId = changeConfigs.get(changeConfigs.size() - 1).getId(); + } + + long endChangeConfigTime = System.currentTimeMillis(); + LogUtil.DEFAULT_LOG.info( + "Check changed gray configs finished,cost:{}, next task running will from start time {}", + endChangeConfigTime - startChangeConfigTime, currentTime); + startTime = currentTime; + } catch (Throwable e) { + LogUtil.DEFAULT_LOG.error("Check changed gray configs error", e); + } finally { + ConfigExecutor.scheduleConfigChangeTask(this, PropertyUtil.getDumpChangeWorkerInterval(), + TimeUnit.MILLISECONDS); + LogUtil.DEFAULT_LOG.info("Next dump gray change will scheduled after {} milliseconds", + PropertyUtil.getDumpChangeWorkerInterval()); + + } + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java index 1ef08c6799a..fb0cc5ec60e 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpConfigHandler.java @@ -44,55 +44,32 @@ public static boolean configDump(ConfigDumpEvent event) { final String group = event.getGroup(); final String namespaceId = event.getNamespaceId(); final String content = event.getContent(); - final String type = event.getType(); final long lastModified = event.getLastModifiedTs(); - //beta - if (event.isBeta()) { - boolean result = false; - if (event.isRemove()) { - result = ConfigCacheService.removeBeta(dataId, group, namespaceId); - if (result) { - ConfigTraceService.logDumpBetaEvent(dataId, group, namespaceId, null, lastModified, - event.getHandleIp(), ConfigTraceService.DUMP_TYPE_REMOVE_OK, - System.currentTimeMillis() - lastModified, 0); - } - return result; - } else { - result = ConfigCacheService.dumpBeta(dataId, group, namespaceId, content, lastModified, - event.getBetaIps(), event.getEncryptedDataKey()); - if (result) { - ConfigTraceService.logDumpBetaEvent(dataId, group, namespaceId, null, lastModified, - event.getHandleIp(), ConfigTraceService.DUMP_TYPE_OK, - System.currentTimeMillis() - lastModified, content.length()); - } - } - - return result; - } - - //tag - if (StringUtils.isNotBlank(event.getTag())) { + + //gray + if (StringUtils.isNotBlank(event.getGrayName())) { // - boolean result; + boolean result = false; if (!event.isRemove()) { - result = ConfigCacheService.dumpTag(dataId, group, namespaceId, event.getTag(), content, lastModified, - event.getEncryptedDataKey()); + result = ConfigCacheService.dumpGray(dataId, group, namespaceId, event.getGrayName(), + event.getGrayRule(), content, lastModified, event.getEncryptedDataKey()); if (result) { - ConfigTraceService.logDumpTagEvent(dataId, group, namespaceId, event.getTag(), null, lastModified, - event.getHandleIp(), ConfigTraceService.DUMP_TYPE_OK, + ConfigTraceService.logDumpGrayNameEvent(dataId, group, namespaceId, event.getGrayName(), null, + lastModified, event.getHandleIp(), ConfigTraceService.DUMP_TYPE_OK, System.currentTimeMillis() - lastModified, content.length()); } } else { - result = ConfigCacheService.removeTag(dataId, group, namespaceId, event.getTag()); + result = ConfigCacheService.removeGray(dataId, group, namespaceId, event.getGrayName()); if (result) { - ConfigTraceService.logDumpTagEvent(dataId, group, namespaceId, event.getTag(), null, lastModified, - event.getHandleIp(), ConfigTraceService.DUMP_TYPE_REMOVE_OK, + ConfigTraceService.logDumpGrayNameEvent(dataId, group, namespaceId, event.getGrayName(), null, + lastModified, event.getHandleIp(), ConfigTraceService.DUMP_TYPE_REMOVE_OK, System.currentTimeMillis() - lastModified, 0); } } + return result; } - + //default if (dataId.equals(AggrWhitelist.AGGRIDS_METADATA)) { AggrWhitelist.load(content); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpRequest.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpRequest.java index 54ad18c9454..8d432bd6fb9 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpRequest.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpRequest.java @@ -19,6 +19,7 @@ /** * dump request. + * * @author shiyiyue */ public class DumpRequest { @@ -29,11 +30,7 @@ public class DumpRequest { String tenant; - private boolean isBeta; - - private boolean isBatch; - - private String tag; + String grayName; private long lastModifiedTs; @@ -63,30 +60,6 @@ public void setTenant(String tenant) { this.tenant = tenant; } - public boolean isBeta() { - return isBeta; - } - - public void setBeta(boolean beta) { - isBeta = beta; - } - - public boolean isBatch() { - return isBatch; - } - - public void setBatch(boolean batch) { - isBatch = batch; - } - - public String getTag() { - return tag; - } - - public void setTag(String tag) { - this.tag = tag; - } - public long getLastModifiedTs() { return lastModifiedTs; } @@ -99,17 +72,26 @@ public String getSourceIp() { return sourceIp; } + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + public void setSourceIp(String sourceIp) { this.sourceIp = sourceIp; } /** * create dump request. - * @param dataId dataId. - * @param group group. - * @param tenant tenant. + * + * @param dataId dataId. + * @param group group. + * @param tenant tenant. * @param lastModifiedTs lastModifiedTs. - * @param sourceIp sourceIp. + * @param sourceIp sourceIp. * @return */ public static DumpRequest create(String dataId, String group, String tenant, long lastModifiedTs, String sourceIp) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java index 5a5ec201173..b03fb229dff 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java @@ -26,19 +26,17 @@ import com.alibaba.nacos.config.server.model.ConfigInfoChanged; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; -import com.alibaba.nacos.config.server.service.dump.processor.DumpAllBetaProcessor; +import com.alibaba.nacos.config.server.service.dump.processor.DumpAllGrayProcessor; import com.alibaba.nacos.config.server.service.dump.processor.DumpAllProcessor; -import com.alibaba.nacos.config.server.service.dump.processor.DumpAllTagProcessor; import com.alibaba.nacos.config.server.service.dump.processor.DumpProcessor; -import com.alibaba.nacos.config.server.service.dump.task.DumpAllBetaTask; +import com.alibaba.nacos.config.server.service.dump.task.DumpAllGrayTask; import com.alibaba.nacos.config.server.service.dump.task.DumpAllTagTask; import com.alibaba.nacos.config.server.service.dump.task.DumpAllTask; import com.alibaba.nacos.config.server.service.dump.task.DumpTask; import com.alibaba.nacos.config.server.service.merge.MergeDatumService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.GroupKey2; @@ -73,9 +71,7 @@ public abstract class DumpService { protected DumpAllProcessor dumpAllProcessor; - protected DumpAllBetaProcessor dumpAllBetaProcessor; - - protected DumpAllTagProcessor dumpAllTagProcessor; + protected DumpAllGrayProcessor dumpAllGrayProcessor; protected ConfigInfoPersistService configInfoPersistService; @@ -85,9 +81,7 @@ public abstract class DumpService { protected ConfigInfoAggrPersistService configInfoAggrPersistService; - protected ConfigInfoBetaPersistService configInfoBetaPersistService; - - protected ConfigInfoTagPersistService configInfoTagPersistService; + protected ConfigInfoGrayPersistService configInfoGrayPersistService; protected MergeDatumService mergeDatumService; @@ -111,12 +105,6 @@ public abstract class DumpService { int total = 0; - private static final String BETA_TABLE_NAME = "config_info_beta"; - - private static final String TAG_TABLE_NAME = "config_info_tag"; - - private int retentionDays = 30; - /** * Here you inject the dependent objects constructively, ensuring that some of the dependent functionality is * initialized ahead of time. @@ -127,22 +115,18 @@ public DumpService(ConfigInfoPersistService configInfoPersistService, NamespacePersistService namespacePersistService, HistoryConfigInfoPersistService historyConfigInfoPersistService, ConfigInfoAggrPersistService configInfoAggrPersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, MergeDatumService mergeDatumService, + ConfigInfoGrayPersistService configInfoGrayPersistService, MergeDatumService mergeDatumService, ServerMemberManager memberManager) { this.configInfoPersistService = configInfoPersistService; + this.configInfoGrayPersistService = configInfoGrayPersistService; this.namespacePersistService = namespacePersistService; this.historyConfigInfoPersistService = historyConfigInfoPersistService; this.configInfoAggrPersistService = configInfoAggrPersistService; - this.configInfoBetaPersistService = configInfoBetaPersistService; - this.configInfoTagPersistService = configInfoTagPersistService; this.mergeDatumService = mergeDatumService; this.memberManager = memberManager; - this.processor = new DumpProcessor(this.configInfoPersistService, this.configInfoBetaPersistService, - this.configInfoTagPersistService); + this.processor = new DumpProcessor(this.configInfoPersistService, this.configInfoGrayPersistService); this.dumpAllProcessor = new DumpAllProcessor(this.configInfoPersistService); - this.dumpAllBetaProcessor = new DumpAllBetaProcessor(this.configInfoBetaPersistService); - this.dumpAllTagProcessor = new DumpAllTagProcessor(this.configInfoTagPersistService); + this.dumpAllGrayProcessor = new DumpAllGrayProcessor(this.configInfoGrayPersistService); this.dumpTaskMgr = new TaskManager("com.alibaba.nacos.server.DumpTaskManager"); this.dumpTaskMgr.setDefaultTaskProcessor(processor); @@ -150,9 +134,6 @@ public DumpService(ConfigInfoPersistService configInfoPersistService, this.dumpAllTaskMgr.setDefaultTaskProcessor(dumpAllProcessor); this.dumpAllTaskMgr.addProcessor(DumpAllTask.TASK_ID, dumpAllProcessor); - this.dumpAllTaskMgr.addProcessor(DumpAllBetaTask.TASK_ID, dumpAllBetaProcessor); - this.dumpAllTaskMgr.addProcessor(DumpAllTagTask.TASK_ID, dumpAllTagProcessor); - DynamicDataSource.getInstance().getDataSource(); NotifyCenter.registerSubscriber(new Subscriber() { @@ -173,12 +154,9 @@ void handleConfigDataChange(Event event) { // Generate ConfigDataChangeEvent concurrently if (event instanceof ConfigDataChangeEvent) { ConfigDataChangeEvent evt = (ConfigDataChangeEvent) event; - DumpRequest dumpRequest = DumpRequest.create(evt.dataId, evt.group, evt.tenant, evt.lastModifiedTs, NetUtils.localIP()); - dumpRequest.setBeta(evt.isBeta); - dumpRequest.setBatch(evt.isBatch); - dumpRequest.setTag(evt.tag); + dumpRequest.setGrayName(evt.grayName); DumpService.this.dump(dumpRequest); } } @@ -230,24 +208,13 @@ public void run() { } /** - * dump all beta processor runner. - */ - class DumpAllBetaProcessorRunner implements Runnable { - - @Override - public void run() { - dumpAllTaskMgr.addTask(DumpAllBetaTask.TASK_ID, new DumpAllBetaTask()); - } - } - - /** - * dump all tag processor runner. + * dump all gray processor runner. */ - class DumpAllTagProcessorRunner implements Runnable { + class DumpAllGrayProcessorRunner implements Runnable { @Override public void run() { - dumpAllTaskMgr.addTask(DumpAllTagTask.TASK_ID, new DumpAllTagTask()); + dumpAllTaskMgr.addTask(DumpAllTagTask.TASK_ID, new DumpAllGrayTask()); } } @@ -262,18 +229,9 @@ protected void dumpOperate() throws NacosException { try { dumpAllConfigInfoOnStartup(dumpAllProcessor); - // update Beta cache - LogUtil.DEFAULT_LOG.info("start clear all config-info-beta."); - ConfigDiskServiceFactory.getInstance().clearAllBeta(); - if (namespacePersistService.isExistTable(BETA_TABLE_NAME)) { - dumpAllBetaProcessor.process(new DumpAllBetaTask()); - } - // update Tag cache - LogUtil.DEFAULT_LOG.info("start clear all config-info-tag."); - ConfigDiskServiceFactory.getInstance().clearAllTag(); - if (namespacePersistService.isExistTable(TAG_TABLE_NAME)) { - dumpAllTagProcessor.process(new DumpAllTagTask()); - } + LogUtil.DEFAULT_LOG.info("start clear all config-info-gray."); + ConfigDiskServiceFactory.getInstance().clearAllGray(); + dumpAllGrayProcessor.process(new DumpAllGrayTask()); // add to dump aggr List configList = configInfoAggrPersistService.findAllAggrGroup(); @@ -301,17 +259,16 @@ protected void dumpOperate() throws NacosException { ConfigExecutor.scheduleConfigTask(new DumpAllProcessorRunner(), initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); - - ConfigExecutor.scheduleConfigTask(new DumpAllBetaProcessorRunner(), initialDelay, + ConfigExecutor.scheduleConfigTask(new DumpAllGrayProcessorRunner(), initialDelay, DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); - ConfigExecutor.scheduleConfigTask(new DumpAllTagProcessorRunner(), initialDelay, - DUMP_ALL_INTERVAL_IN_MINUTE, TimeUnit.MINUTES); ConfigExecutor.scheduleConfigChangeTask( new DumpChangeConfigWorker(this.configInfoPersistService, this.historyConfigInfoPersistService, currentTime), random.nextInt((int) PropertyUtil.getDumpChangeWorkerInterval()), TimeUnit.MILLISECONDS); - + ConfigExecutor.scheduleConfigChangeTask( + new DumpChangeGrayConfigWorker(this.configInfoGrayPersistService, currentTime), + random.nextInt((int) PropertyUtil.getDumpChangeWorkerInterval()), TimeUnit.MILLISECONDS); } HistoryConfigCleaner cleaner = HistoryConfigCleanerManager.getHistoryConfigCleaner( @@ -342,15 +299,9 @@ private void dumpAllConfigInfoOnStartup(DumpAllProcessor dumpAllProcessor) { * @param dumpRequest dumpRequest. */ public void dump(DumpRequest dumpRequest) { - if (dumpRequest.isBeta()) { - dumpBeta(dumpRequest.getDataId(), dumpRequest.getGroup(), dumpRequest.getTenant(), - dumpRequest.getLastModifiedTs(), dumpRequest.getSourceIp()); - } else if (dumpRequest.isBatch()) { - dumpBatch(dumpRequest.getDataId(), dumpRequest.getGroup(), dumpRequest.getTenant(), - dumpRequest.getLastModifiedTs(), dumpRequest.getSourceIp()); - } else if (StringUtils.isNotBlank(dumpRequest.getTag())) { - dumpTag(dumpRequest.getDataId(), dumpRequest.getGroup(), dumpRequest.getTenant(), dumpRequest.getTag(), - dumpRequest.getLastModifiedTs(), dumpRequest.getSourceIp()); + if (StringUtils.isNotBlank(dumpRequest.getGrayName())) { + dumpGray(dumpRequest.getDataId(), dumpRequest.getGroup(), dumpRequest.getTenant(), + dumpRequest.getGrayName(), dumpRequest.getLastModifiedTs(), dumpRequest.getSourceIp()); } else { dumpFormal(dumpRequest.getDataId(), dumpRequest.getGroup(), dumpRequest.getTenant(), dumpRequest.getLastModifiedTs(), dumpRequest.getSourceIp()); @@ -369,59 +320,27 @@ public void dump(DumpRequest dumpRequest) { private void dumpFormal(String dataId, String group, String tenant, long lastModified, String handleIp) { String groupKey = GroupKey2.getKey(dataId, group, tenant); String taskKey = groupKey; - dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, false, false, false, null, lastModified, handleIp)); + dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, null, lastModified, handleIp)); DUMP_LOG.info("[dump] add formal task. groupKey={}", groupKey); } /** - * dump beta. - * - * @param dataId dataId. - * @param group group. - * @param tenant tenant. - * @param lastModified lastModified. - * @param handleIp handleIp. - */ - private void dumpBeta(String dataId, String group, String tenant, long lastModified, String handleIp) { - String groupKey = GroupKey2.getKey(dataId, group, tenant); - String taskKey = groupKey + "+beta"; - dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, true, false, false, null, lastModified, handleIp)); - DUMP_LOG.info("[dump] add beta task. groupKey={}", groupKey); - - } - - /** - * dump batch. - * - * @param dataId dataId. - * @param group group. - * @param tenant tenant. - * @param lastModified lastModified. - * @param handleIp handleIp. - */ - private void dumpBatch(String dataId, String group, String tenant, long lastModified, String handleIp) { - String groupKey = GroupKey2.getKey(dataId, group, tenant); - String taskKey = groupKey + "+batch"; - dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, false, true, false, null, lastModified, handleIp)); - DUMP_LOG.info("[dump] add batch task. groupKey={}", dataId + "+" + group); - } - - /** - * dump tag. + * dump gray. * * @param dataId dataId. * @param group group. * @param tenant tenant. - * @param tag tag. + * @param grayName grayName. * @param lastModified lastModified. * @param handleIp handleIp. */ - private void dumpTag(String dataId, String group, String tenant, String tag, long lastModified, String handleIp) { + private void dumpGray(String dataId, String group, String tenant, String grayName, long lastModified, + String handleIp) { String groupKey = GroupKey2.getKey(dataId, group, tenant); - String taskKey = groupKey + "+tag+" + tag; - dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, false, false, true, tag, lastModified, handleIp)); - DUMP_LOG.info("[dump] add tag task. groupKey={},tag={}", groupKey, tag); + String taskKey = groupKey + "+gray+" + grayName; + dumpTaskMgr.addTask(taskKey, new DumpTask(groupKey, grayName, lastModified, handleIp)); + DUMP_LOG.info("[dump] add gray task. groupKey={},grayName={}", groupKey, grayName); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java index 4895cbdf13c..ea0c9ce5f94 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/EmbeddedDumpService.java @@ -21,19 +21,18 @@ import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.common.utils.ThreadUtils; import com.alibaba.nacos.config.server.service.merge.MergeDatumService; -import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; -import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.consistency.ProtocolMetaData; import com.alibaba.nacos.consistency.cp.CPProtocol; import com.alibaba.nacos.consistency.cp.MetadataKey; import com.alibaba.nacos.core.cluster.ServerMemberManager; import com.alibaba.nacos.core.distributed.ProtocolManager; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; import com.alibaba.nacos.core.utils.GlobalExecutor; +import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; import com.alibaba.nacos.persistence.constants.PersistenceConstant; import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; import com.alibaba.nacos.sys.env.EnvUtil; @@ -77,11 +76,10 @@ public EmbeddedDumpService(ConfigInfoPersistService configInfoPersistService, NamespacePersistService namespacePersistService, HistoryConfigInfoPersistService historyConfigInfoPersistService, ConfigInfoAggrPersistService configInfoAggrPersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, MergeDatumService mergeDatumService, + ConfigInfoGrayPersistService configInfoGrayPersistService, MergeDatumService mergeDatumService, ServerMemberManager memberManager, ProtocolManager protocolManager) { super(configInfoPersistService, namespacePersistService, historyConfigInfoPersistService, - configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, + configInfoAggrPersistService, configInfoGrayPersistService, mergeDatumService, memberManager); this.protocolManager = protocolManager; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java index 3b2b20fba1d..2fc865fe9a3 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/ExternalDumpService.java @@ -17,14 +17,13 @@ package com.alibaba.nacos.config.server.service.dump; import com.alibaba.nacos.config.server.service.merge.MergeDatumService; -import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; -import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.core.cluster.ServerMemberManager; +import com.alibaba.nacos.core.namespace.repository.NamespacePersistService; +import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.DependsOn; import org.springframework.stereotype.Component; @@ -38,7 +37,7 @@ */ @Conditional(ConditionOnExternalStorage.class) @Component -@DependsOn({"rpcConfigChangeNotifier"}) +@DependsOn({"rpcConfigChangeNotifier", "configGrayModelMigrateService"}) public class ExternalDumpService extends DumpService { /** @@ -51,12 +50,10 @@ public ExternalDumpService(ConfigInfoPersistService configInfoPersistService, NamespacePersistService namespacePersistService, HistoryConfigInfoPersistService historyConfigInfoPersistService, ConfigInfoAggrPersistService configInfoAggrPersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService, MergeDatumService mergeDatumService, + ConfigInfoGrayPersistService configInfoGrayPersistService, MergeDatumService mergeDatumService, ServerMemberManager memberManager) { super(configInfoPersistService, namespacePersistService, historyConfigInfoPersistService, - configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, - mergeDatumService, memberManager); + configInfoAggrPersistService, configInfoGrayPersistService, mergeDatumService, memberManager); } @PostConstruct diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigDiskService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigDiskService.java index 4983704872e..97169574013 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigDiskService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigDiskService.java @@ -35,57 +35,49 @@ public interface ConfigDiskService { * @throws IOException io exception. */ void saveToDisk(String dataId, String group, String tenant, String content) throws IOException; - - /** - * Save beta information to disk. - * - * @param dataId dataId. - * @param group group. - * @param tenant tenant. - * @param content content. - * @throws IOException io exception. - */ - void saveBetaToDisk(String dataId, String group, String tenant, String content) throws IOException; /** - * Save tag information to disk. + * Save gray information to disk. * * @param dataId dataId. * @param group group. * @param tenant tenant. - * @param tag tag. + * @param grayName grayName. * @param content content. * @throws IOException io exception. */ - void saveTagToDisk(String dataId, String group, String tenant, String tag, String content) throws IOException; + void saveGrayToDisk(String dataId, String group, String tenant, String grayName, String content) throws IOException; /** - * Deletes configuration files on disk. + * Deletes gray configuration files on disk. * * @param dataId dataId. * @param group group. * @param tenant tenant. + * @param grayName grayName. */ - void removeConfigInfo(String dataId, String group, String tenant); + void removeConfigInfo4Gray(String dataId, String group, String tenant, String grayName); /** - * Deletes beta configuration files on disk. + * Returns the content of the gray cache file in server. * * @param dataId dataId. * @param group group. * @param tenant tenant. + * @param grayName grayName. + * @return gray content, null if not exist. + * @throws IOException io exception. */ - void removeConfigInfo4Beta(String dataId, String group, String tenant); + String getGrayContent(String dataId, String group, String tenant, String grayName) throws IOException; /** - * Deletes tag configuration files on disk. + * Deletes configuration files on disk. * * @param dataId dataId. * @param group group. * @param tenant tenant. - * @param tag tag. */ - void removeConfigInfo4Tag(String dataId, String group, String tenant, String tag); + void removeConfigInfo(String dataId, String group, String tenant); /** * Returns the content of the cache file in server. @@ -98,42 +90,14 @@ public interface ConfigDiskService { */ String getContent(String dataId, String group, String tenant) throws IOException; - /** - * Returns the beta content of cache file in server. - * - * @param dataId dataId. - * @param group group. - * @param tenant tenant. - * @return content, null if not exist. - * @throws IOException io exception. - */ - String getBetaContent(String dataId, String group, String tenant) throws IOException; - - /** - * Returns the path of the tag cache file in server. - * - * @param dataId dataId. - * @param group group. - * @param tenant tenant. - * @param tag tag. - * @return tag content, null if not exist. - * @throws IOException io exception. - */ - String getTagContent(String dataId, String group, String tenant, String tag) throws IOException; - /** * Clear all config file. */ void clearAll(); /** - * Clear all beta config file. - */ - void clearAllBeta(); - - /** - * Clear all tag config file. + * Clear all gray config file. */ - void clearAllTag(); + void clearAllGray(); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskService.java index a9e34250710..61da13b3a91 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskService.java @@ -17,7 +17,6 @@ package com.alibaba.nacos.config.server.service.dump.disk; import com.alibaba.nacos.api.utils.StringUtils; -import com.alibaba.nacos.common.pathencoder.PathEncoderManager; import com.alibaba.nacos.common.utils.IoUtils; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.sys.env.EnvUtil; @@ -42,17 +41,9 @@ public class ConfigRawDiskService implements ConfigDiskService { private static final String TENANT_BASE_DIR = File.separator + "data" + File.separator + "tenant-config-data"; - private static final String BETA_DIR = File.separator + "data" + File.separator + "beta-data"; + private static final String GRAY_DIR = File.separator + "data" + File.separator + "gray-data"; - private static final String TENANT_BETA_DIR = File.separator + "data" + File.separator + "tenant-beta-data"; - - private static final String TAG_DIR = File.separator + "data" + File.separator + "tag-data"; - - private static final String TENANT_TAG_DIR = File.separator + "data" + File.separator + "tenant-tag-data"; - - private static final String BATCH_DIR = File.separator + "data" + File.separator + "batch-data"; - - private static final String TENANT_BATCH_DIR = File.separator + "data" + File.separator + "tenant-batch-data"; + private static final String TENANT_GRAY_DIR = File.separator + "data" + File.separator + "tenant-gray-data"; /** * Save configuration information to disk. @@ -66,10 +57,6 @@ public void saveToDisk(String dataId, String group, String tenant, String conten * Returns the path of the server cache file. */ private static File targetFile(String dataId, String group, String tenant) { - // fix https://github.com/alibaba/nacos/issues/10067 - dataId = PathEncoderManager.getInstance().encode(dataId); - group = PathEncoderManager.getInstance().encode(group); - tenant = PathEncoderManager.getInstance().encode(tenant); File file = null; if (StringUtils.isBlank(tenant)) { file = new File(EnvUtil.getNacosHome(), BASE_DIR); @@ -83,61 +70,36 @@ private static File targetFile(String dataId, String group, String tenant) { } /** - * Returns the path of cache file in server. - */ - private static File targetBetaFile(String dataId, String group, String tenant) { - // fix https://github.com/alibaba/nacos/issues/10067 - dataId = PathEncoderManager.getInstance().encode(dataId); - group = PathEncoderManager.getInstance().encode(group); - tenant = PathEncoderManager.getInstance().encode(tenant); - File file = null; - if (StringUtils.isBlank(tenant)) { - file = new File(EnvUtil.getNacosHome(), BETA_DIR); - } else { - file = new File(EnvUtil.getNacosHome(), TENANT_BETA_DIR); - file = new File(file, tenant); - } - file = new File(file, group); - file = new File(file, dataId); - return file; - } - - /** - * Returns the path of the tag cache file in server. + * Returns the path of the gray cache file in server. */ - private static File targetTagFile(String dataId, String group, String tenant, String tag) { - // fix https://github.com/alibaba/nacos/issues/10067 - dataId = PathEncoderManager.getInstance().encode(dataId); - group = PathEncoderManager.getInstance().encode(group); - tenant = PathEncoderManager.getInstance().encode(tenant); + private static File targetGrayFile(String dataId, String group, String tenant, String grayName) { File file = null; if (StringUtils.isBlank(tenant)) { - file = new File(EnvUtil.getNacosHome(), TAG_DIR); + file = new File(EnvUtil.getNacosHome(), GRAY_DIR); } else { - file = new File(EnvUtil.getNacosHome(), TENANT_TAG_DIR); + file = new File(EnvUtil.getNacosHome(), TENANT_GRAY_DIR); file = new File(file, tenant); } file = new File(file, group); file = new File(file, dataId); - file = new File(file, tag); + file = new File(file, grayName); return file; } /** - * Save beta information to disk. + * Returns the path of the gray content cache file in server. */ - public void saveBetaToDisk(String dataId, String group, String tenant, String content) throws IOException { - File targetFile = targetBetaFile(dataId, group, tenant); - FileUtils.writeStringToFile(targetFile, content, ENCODE_UTF8); + private static File targetGrayContentFile(String dataId, String group, String tenant, String grayName) { + return targetGrayFile(dataId, group, tenant, grayName); } /** - * Save tag information to disk. + * Save gray information to disk. */ - public void saveTagToDisk(String dataId, String group, String tenant, String tag, String content) + public void saveGrayToDisk(String dataId, String group, String tenant, String grayName, String content) throws IOException { - File targetFile = targetTagFile(dataId, group, tenant, tag); - FileUtils.writeStringToFile(targetFile, content, ENCODE_UTF8); + File targetGrayContentFile = targetGrayContentFile(dataId, group, tenant, grayName); + FileUtils.writeStringToFile(targetGrayContentFile, content, ENCODE_UTF8); } /** @@ -148,17 +110,10 @@ public void removeConfigInfo(String dataId, String group, String tenant) { } /** - * Deletes beta configuration files on disk. + * Deletes gray configuration files on disk. */ - public void removeConfigInfo4Beta(String dataId, String group, String tenant) { - FileUtils.deleteQuietly(targetBetaFile(dataId, group, tenant)); - } - - /** - * Deletes tag configuration files on disk. - */ - public void removeConfigInfo4Tag(String dataId, String group, String tenant, String tag) { - FileUtils.deleteQuietly(targetTagFile(dataId, group, tenant, tag)); + public void removeConfigInfo4Gray(String dataId, String group, String tenant, String grayName) { + FileUtils.deleteQuietly(targetGrayContentFile(dataId, group, tenant, grayName)); } private static String file2String(File file) throws IOException { @@ -169,19 +124,10 @@ private static String file2String(File file) throws IOException { } /** - * Returns the path of cache file in server. + * Returns the content of the gray cache file in server. */ - public String getBetaContent(String dataId, String group, String tenant) throws IOException { - File file = targetBetaFile(dataId, group, tenant); - return file2String(file); - } - - /** - * Returns the path of the tag cache file in server. - */ - public String getTagContent(String dataId, String group, String tenant, String tag) throws IOException { - File file = targetTagFile(dataId, group, tenant, tag); - return file2String(file); + public String getGrayContent(String dataId, String group, String tenant, String grayName) throws IOException { + return file2String(targetGrayContentFile(dataId, group, tenant, grayName)); } public String getContent(String dataId, String group, String tenant) throws IOException { @@ -220,39 +166,21 @@ public void clearAll() { } /** - * Clear all beta config file. - */ - public void clearAllBeta() { - File file = new File(EnvUtil.getNacosHome(), BETA_DIR); - if (!file.exists() || FileUtils.deleteQuietly(file)) { - LogUtil.DEFAULT_LOG.info("clear all config-info-beta success."); - } else { - LogUtil.DEFAULT_LOG.warn("clear all config-info-beta failed."); - } - File fileTenant = new File(EnvUtil.getNacosHome(), TENANT_BETA_DIR); - if (!fileTenant.exists() || FileUtils.deleteQuietly(fileTenant)) { - LogUtil.DEFAULT_LOG.info("clear all config-info-beta-tenant success."); - } else { - LogUtil.DEFAULT_LOG.warn("clear all config-info-beta-tenant failed."); - } - } - - /** - * Clear all tag config file. + * Clear all gray config file. */ - public void clearAllTag() { - File file = new File(EnvUtil.getNacosHome(), TAG_DIR); + public void clearAllGray() { + File file = new File(EnvUtil.getNacosHome(), GRAY_DIR); if (!file.exists() || FileUtils.deleteQuietly(file)) { - LogUtil.DEFAULT_LOG.info("clear all config-info-tag success."); + LogUtil.DEFAULT_LOG.info("clear all config-info-gray success."); } else { - LogUtil.DEFAULT_LOG.warn("clear all config-info-tag failed."); + LogUtil.DEFAULT_LOG.warn("clear all config-info-gray failed."); } - File fileTenant = new File(EnvUtil.getNacosHome(), TENANT_TAG_DIR); + File fileTenant = new File(EnvUtil.getNacosHome(), TENANT_GRAY_DIR); if (!fileTenant.exists() || FileUtils.deleteQuietly(fileTenant)) { - LogUtil.DEFAULT_LOG.info("clear all config-info-tag-tenant success."); + LogUtil.DEFAULT_LOG.info("clear all config-info-gray-tenant success."); } else { - LogUtil.DEFAULT_LOG.warn("clear all config-info-tag-tenant failed."); + LogUtil.DEFAULT_LOG.warn("clear all config-info-gray-tenant failed."); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java index 0eb85f98be6..0da0cc40284 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRocksDbDiskService.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service.dump.disk; +import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.sys.env.EnvUtil; @@ -32,6 +33,7 @@ import java.util.Map; import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_UTF8; +import static com.alibaba.nacos.config.server.constant.Constants.NULL; /** * config rocks db disk service. @@ -45,11 +47,7 @@ public class ConfigRocksDbDiskService implements ConfigDiskService { private static final String BASE_DIR = ROCKSDB_DATA + "config-data"; - private static final String BETA_DIR = ROCKSDB_DATA + "beta-data"; - - private static final String TAG_DIR = ROCKSDB_DATA + "tag-data"; - - private static final String BATCH_DIR = ROCKSDB_DATA + "batch-data"; + private static final String GRAY_DIR = ROCKSDB_DATA + "gray-data"; private static final long DEFAULT_WRITE_BUFFER_MB = 32; @@ -79,13 +77,19 @@ private void deleteDirIfExist(String dir) { public ConfigRocksDbDiskService() { createDirIfNotExist(BASE_DIR); - createDirIfNotExist(BETA_DIR); - createDirIfNotExist(TAG_DIR); - createDirIfNotExist(BATCH_DIR); + createDirIfNotExist(GRAY_DIR); + } private byte[] getKeyByte(String dataId, String group, String tenant, String tag) throws IOException { String[] keys = new String[] {dataId, group, tenant, tag}; + return getKeyByte(keys); + } + + private byte[] getKeyByte(String... keys) throws IOException { + if (keys == null || keys.length == 0) { + return NULL.getBytes(ENCODE_UTF8); + } StringBuilder stringBuilder = new StringBuilder(); for (String key : keys) { if (StringUtils.isBlank(key)) { @@ -134,26 +138,30 @@ public void saveToDiskInner(String type, String dataId, String group, String ten } /** - * Save configuration information to disk. + * save config to disk. */ - public void saveToDisk(String dataId, String group, String tenant, String content) throws IOException { - saveToDiskInner(BASE_DIR, dataId, group, tenant, content); + public void saveGrayToDiskInner(String type, String dataId, String group, String tenant, String grayName, + String content) throws IOException { + try { + initAndGetDB(type).put(getKeyByte(dataId, group, tenant, grayName), content.getBytes(ENCODE_UTF8)); + } catch (RocksDBException e) { + throw new IOException(e); + } } /** - * Save beta information to disk. + * Save configuration information to disk. */ - public void saveBetaToDisk(String dataId, String group, String tenant, String content) throws IOException { - saveToDiskInner(BETA_DIR, dataId, group, tenant, content); - + public void saveToDisk(String dataId, String group, String tenant, String content) throws IOException { + saveToDiskInner(BASE_DIR, dataId, group, tenant, content); } /** * Save tag information to disk. */ - public void saveTagToDisk(String dataId, String group, String tenant, String tag, String content) + public void saveGrayToDisk(String dataId, String group, String tenant, String grayName, String content) throws IOException { - saveToDiskInner(TAG_DIR, dataId, group, tenant, tag, content); + saveGrayToDiskInner(GRAY_DIR, dataId, group, tenant, grayName, content); } @@ -165,17 +173,10 @@ public void removeConfigInfo(String dataId, String group, String tenant) { } /** - * Deletes beta configuration files on disk. + * Deletes gray configuration files on disk. */ - public void removeConfigInfo4Beta(String dataId, String group, String tenant) { - removeContentInner(BETA_DIR, dataId, group, tenant, null); - } - - /** - * Deletes tag configuration files on disk. - */ - public void removeConfigInfo4Tag(String dataId, String group, String tenant, String tag) { - removeContentInner(TAG_DIR, dataId, group, tenant, tag); + public void removeConfigInfo4Gray(String dataId, String group, String tenant, String grayName) { + removeGrayInner(GRAY_DIR, dataId, group, tenant, grayName); } @@ -186,7 +187,7 @@ private String byte2String(byte[] bytes) throws IOException { return new String(bytes, ENCODE_UTF8); } - RocksDB initAndGetDB(String dir) throws RocksDBException { + RocksDB initAndGetDB(String dir) throws IOException, RocksDBException { if (rocksDbMap.containsKey(dir)) { return rocksDbMap.get(dir); } else { @@ -220,11 +221,11 @@ private String getContentInner(String type, String dataId, String group, String } } - private String getTagContentInner(String type, String dataId, String group, String tenant, String tag) + private String getGrayInner(String type, String dataId, String group, String tenant, String grayName) throws IOException { byte[] bytes = null; try { - bytes = initAndGetDB(type).get(getKeyByte(dataId, group, tenant, tag)); + bytes = initAndGetDB(type).get(getKeyByte(dataId, group, tenant, grayName)); return byte2String(bytes); } catch (RocksDBException e) { throw new IOException(e); @@ -240,24 +241,30 @@ private void removeContentInner(String type, String dataId, String group, String } } - /** - * Returns the path of cache file in server. - */ - public String getBetaContent(String dataId, String group, String tenant) throws IOException { - return getContentInner(BETA_DIR, dataId, group, tenant); + private void removeGrayInner(String type, String dataId, String group, String tenant, String grayName) { + try { + initAndGetDB(type).delete(getKeyByte(dataId, group, tenant, grayName)); + } catch (Exception e) { + LogUtil.DEFAULT_LOG.warn("Remove dir=[{}] config fail,dataId={},group={},tenant={},error={}", type, dataId, + group, tenant, e.getCause()); + } } /** - * Returns the path of the tag cache file in server. + * Returns the path of the gray content cache file in server. */ - public String getTagContent(String dataId, String group, String tenant, String tag) throws IOException { - return getTagContentInner(TAG_DIR, dataId, group, tenant, tag); + public String getGrayContent(String dataId, String group, String tenant, String grayName) throws IOException { + return getGrayInner(GRAY_DIR, dataId, group, tenant, grayName); } public String getContent(String dataId, String group, String tenant) throws IOException { return getContentInner(BASE_DIR, dataId, group, tenant); } + public String getLocalConfigMd5(String dataId, String group, String tenant, String encode) throws IOException { + return MD5Utils.md5Hex(getContentInner(BASE_DIR, dataId, group, tenant), encode); + } + Options createOptions(String dir) { DBOptions dbOptions = new DBOptions(); dbOptions.setMaxBackgroundJobs(Runtime.getRuntime().availableProcessors()); @@ -326,35 +333,19 @@ public void clearAll() { } /** - * Clear all beta config file. - */ - public void clearAllBeta() { - try { - if (rocksDbMap.containsKey(BETA_DIR)) { - rocksDbMap.get(BETA_DIR).close(); - RocksDB.destroyDB(EnvUtil.getNacosHome() + BETA_DIR, new Options()); - } - deleteDirIfExist(BETA_DIR); - LogUtil.DEFAULT_LOG.info("clear all config-info-beta success."); - } catch (RocksDBException e) { - LogUtil.DEFAULT_LOG.warn("clear all config-info-beta failed.", e); - } - } - - /** - * Clear all tag config file. + * Clear all gray config file. */ - public void clearAllTag() { + public void clearAllGray() { try { - if (rocksDbMap.containsKey(TAG_DIR)) { - rocksDbMap.get(TAG_DIR).close(); - RocksDB.destroyDB(EnvUtil.getNacosHome() + TAG_DIR, new Options()); + if (rocksDbMap.containsKey(GRAY_DIR)) { + rocksDbMap.get(GRAY_DIR).close(); + RocksDB.destroyDB(EnvUtil.getNacosHome() + GRAY_DIR, new Options()); } - deleteDirIfExist(TAG_DIR); - LogUtil.DEFAULT_LOG.info("clear all config-info-tag success."); + deleteDirIfExist(GRAY_DIR); + LogUtil.DEFAULT_LOG.info("clear all config-info-gray success."); } catch (RocksDBException e) { - LogUtil.DEFAULT_LOG.warn("clear all config-info-tag failed.", e); + LogUtil.DEFAULT_LOG.warn("clear all config-info-gray failed.", e); } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllBetaProcessor.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllBetaProcessor.java deleted file mode 100644 index 47b7aab0e5b..00000000000 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllBetaProcessor.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 1999-2018 Alibaba Group Holding Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.alibaba.nacos.config.server.service.dump.processor; - -import com.alibaba.nacos.common.task.NacosTask; -import com.alibaba.nacos.common.task.NacosTaskProcessor; -import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; -import com.alibaba.nacos.config.server.service.ConfigCacheService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; -import com.alibaba.nacos.config.server.utils.GroupKey2; -import com.alibaba.nacos.config.server.utils.LogUtil; -import com.alibaba.nacos.persistence.model.Page; - -import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; - -/** - * Dump all beta processor. - * - * @author Nacos - * @author Wei.Wang - * @date 2020/7/5 12:18 PM - */ -public class DumpAllBetaProcessor implements NacosTaskProcessor { - - public DumpAllBetaProcessor(ConfigInfoBetaPersistService configInfoBetaPersistService) { - this.configInfoBetaPersistService = configInfoBetaPersistService; - } - - @Override - public boolean process(NacosTask task) { - int rowCount = configInfoBetaPersistService.configInfoBetaCount(); - int pageCount = (int) Math.ceil(rowCount * 1.0 / PAGE_SIZE); - - int actualRowCount = 0; - for (int pageNo = 1; pageNo <= pageCount; pageNo++) { - Page page = configInfoBetaPersistService.findAllConfigInfoBetaForDumpAll(pageNo, - PAGE_SIZE); - if (page != null) { - for (ConfigInfoBetaWrapper cf : page.getPageItems()) { - boolean result = ConfigCacheService.dumpBeta(cf.getDataId(), cf.getGroup(), cf.getTenant(), - cf.getContent(), cf.getLastModified(), cf.getBetaIps(), cf.getEncryptedDataKey()); - LogUtil.DUMP_LOG.info("[dump-all-beta-ok] result={}, {}, {}, length={}, md5={}", result, - GroupKey2.getKey(cf.getDataId(), cf.getGroup()), cf.getLastModified(), - cf.getContent().length(), cf.getMd5()); - } - - actualRowCount += page.getPageItems().size(); - DEFAULT_LOG.info("[all-dump-beta] {} / {}", actualRowCount, rowCount); - } - } - return true; - } - - static final int PAGE_SIZE = 1000; - - final ConfigInfoBetaPersistService configInfoBetaPersistService; -} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllTagProcessor.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllGrayProcessor.java similarity index 61% rename from config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllTagProcessor.java rename to config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllGrayProcessor.java index 2e4e4e7dfc0..43dd5cf18af 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllTagProcessor.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllGrayProcessor.java @@ -18,53 +18,54 @@ import com.alibaba.nacos.common.task.NacosTask; import com.alibaba.nacos.common.task.NacosTaskProcessor; -import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; -import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.service.ConfigCacheService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.LogUtil; +import com.alibaba.nacos.persistence.model.Page; import static com.alibaba.nacos.config.server.utils.LogUtil.DEFAULT_LOG; +import static com.alibaba.nacos.config.server.utils.PropertyUtil.getAllDumpPageSize; /** - * Dump all tag processor. + * Dump all gray processor. * * @author Nacos - * @date 2020/7/5 12:18 PM + * @datete 2024/02/20 */ -public class DumpAllTagProcessor implements NacosTaskProcessor { +public class DumpAllGrayProcessor implements NacosTaskProcessor { - public DumpAllTagProcessor(ConfigInfoTagPersistService configInfoTagPersistService) { - this.configInfoTagPersistService = configInfoTagPersistService; + public DumpAllGrayProcessor(ConfigInfoGrayPersistService configInfoGrayPersistService) { + this.configInfoGrayPersistService = configInfoGrayPersistService; } @Override public boolean process(NacosTask task) { - int rowCount = configInfoTagPersistService.configInfoTagCount(); + int rowCount = configInfoGrayPersistService.configInfoGrayCount(); int pageCount = (int) Math.ceil(rowCount * 1.0 / PAGE_SIZE); int actualRowCount = 0; for (int pageNo = 1; pageNo <= pageCount; pageNo++) { - Page page = configInfoTagPersistService.findAllConfigInfoTagForDumpAll(pageNo, PAGE_SIZE); + Page page = configInfoGrayPersistService.findAllConfigInfoGrayForDumpAll(pageNo, PAGE_SIZE); if (page != null) { - for (ConfigInfoTagWrapper cf : page.getPageItems()) { + for (ConfigInfoGrayWrapper cf : page.getPageItems()) { boolean result = ConfigCacheService - .dumpTag(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getTag(), cf.getContent(), + .dumpGray(cf.getDataId(), cf.getGroup(), cf.getTenant(), cf.getGrayName(), cf.getGrayRule(), cf.getContent(), cf.getLastModified(), cf.getEncryptedDataKey()); - LogUtil.DUMP_LOG.info("[dump-all-Tag-ok] result={}, {}, {}, length={}, md5={}", result, + LogUtil.DUMP_LOG.info("[dump-all-gray-ok] result={}, {}, {}, length={}, md5={}, grayName={}", result, GroupKey2.getKey(cf.getDataId(), cf.getGroup()), cf.getLastModified(), - cf.getContent().length(), cf.getMd5()); + cf.getContent().length(), cf.getMd5(), cf.getGrayName()); } actualRowCount += page.getPageItems().size(); - DEFAULT_LOG.info("[all-dump-tag] {} / {}", actualRowCount, rowCount); + DEFAULT_LOG.info("[all-dump-gray] {} / {}", actualRowCount, rowCount); } } return true; } - static final int PAGE_SIZE = 1000; + static final int PAGE_SIZE = getAllDumpPageSize(); - final ConfigInfoTagPersistService configInfoTagPersistService; + final ConfigInfoGrayPersistService configInfoGrayPersistService; } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpProcessor.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpProcessor.java index 8c5b2267feb..600ec730fd6 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpProcessor.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/processor/DumpProcessor.java @@ -19,15 +19,13 @@ import com.alibaba.nacos.common.task.NacosTask; import com.alibaba.nacos.common.task.NacosTaskProcessor; import com.alibaba.nacos.common.utils.StringUtils; -import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; -import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; import com.alibaba.nacos.config.server.model.event.ConfigDumpEvent; import com.alibaba.nacos.config.server.service.dump.DumpConfigHandler; import com.alibaba.nacos.config.server.service.dump.task.DumpTask; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.LogUtil; @@ -43,16 +41,12 @@ public class DumpProcessor implements NacosTaskProcessor { final ConfigInfoPersistService configInfoPersistService; - final ConfigInfoBetaPersistService configInfoBetaPersistService; - - final ConfigInfoTagPersistService configInfoTagPersistService; + final ConfigInfoGrayPersistService configInfoGrayPersistService; public DumpProcessor(ConfigInfoPersistService configInfoPersistService, - ConfigInfoBetaPersistService configInfoBetaPersistService, - ConfigInfoTagPersistService configInfoTagPersistService) { + ConfigInfoGrayPersistService configInfoGrayPersistService) { this.configInfoPersistService = configInfoPersistService; - this.configInfoBetaPersistService = configInfoBetaPersistService; - this.configInfoTagPersistService = configInfoTagPersistService; + this.configInfoGrayPersistService = configInfoGrayPersistService; } @Override @@ -64,37 +58,26 @@ public boolean process(NacosTask task) { String tenant = pair[2]; long lastModifiedOut = dumpTask.getLastModified(); String handleIp = dumpTask.getHandleIp(); - boolean isBeta = dumpTask.isBeta(); - String tag = dumpTask.getTag(); + String grayName = dumpTask.getGrayName(); + ConfigDumpEvent.ConfigDumpEventBuilder build = ConfigDumpEvent.builder().namespaceId(tenant).dataId(dataId) - .group(group).isBeta(isBeta).tag(tag).handleIp(handleIp); + .group(group).grayName(grayName).handleIp(handleIp); String type = "formal"; - if (isBeta) { - type = "beta"; - } else if (StringUtils.isNotBlank(tag)) { - type = "tag-" + tag; + if (StringUtils.isNotBlank(grayName)) { + type = grayName; } LogUtil.DUMP_LOG.info("[dump] process {} task. groupKey={}", type, dumpTask.getGroupKey()); - if (isBeta) { - // if publish beta, then dump config, update beta cache - ConfigInfoBetaWrapper cf = configInfoBetaPersistService.findConfigInfo4Beta(dataId, group, tenant); - build.remove(Objects.isNull(cf)); - build.betaIps(Objects.isNull(cf) ? null : cf.getBetaIps()); - build.content(Objects.isNull(cf) ? null : cf.getContent()); - build.type(Objects.isNull(cf) ? null : cf.getType()); - build.encryptedDataKey(Objects.isNull(cf) ? null : cf.getEncryptedDataKey()); - build.lastModifiedTs(Objects.isNull(cf) ? lastModifiedOut : cf.getLastModified()); - return DumpConfigHandler.configDump(build.build()); - } - - if (StringUtils.isNotBlank(tag)) { - ConfigInfoTagWrapper cf = configInfoTagPersistService.findConfigInfo4Tag(dataId, group, tenant, tag); + if (StringUtils.isNotBlank(grayName)) { + ConfigInfoGrayWrapper cf = configInfoGrayPersistService.findConfigInfo4Gray(dataId, group, tenant, + grayName); build.remove(Objects.isNull(cf)); build.content(Objects.isNull(cf) ? null : cf.getContent()); build.type(Objects.isNull(cf) ? null : cf.getType()); build.encryptedDataKey(Objects.isNull(cf) ? null : cf.getEncryptedDataKey()); build.lastModifiedTs(Objects.isNull(cf) ? lastModifiedOut : cf.getLastModified()); + build.grayName(grayName); + build.grayRule(Objects.isNull(cf) ? null : cf.getGrayRule()); return DumpConfigHandler.configDump(build.build()); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpAllGrayTask.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpAllGrayTask.java new file mode 100644 index 00000000000..dfdc4ee8c3d --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpAllGrayTask.java @@ -0,0 +1,34 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.dump.task; + +import com.alibaba.nacos.common.task.AbstractDelayTask; + +/** + * Dump all gray task. + * + * @author Nacos + * @date 2024/3/5 + */ +public class DumpAllGrayTask extends AbstractDelayTask { + + @Override + public void merge(AbstractDelayTask task) { + } + + public static final String TASK_ID = "dumpAllGrayConfigTask"; +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpTask.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpTask.java index 9de5ea4544f..ca83b45eea3 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpTask.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/task/DumpTask.java @@ -25,19 +25,11 @@ */ public class DumpTask extends AbstractDelayTask { - public DumpTask(String groupKey, boolean isBeta, boolean isBatch, boolean isTag, String tag, long lastModified, - String handleIp) { + public DumpTask(String groupKey, String grayName, long lastModified, String handleIp) { this.groupKey = groupKey; this.lastModified = lastModified; this.handleIp = handleIp; - this.isBeta = isBeta; - if (isTag) { - this.tag = tag; - } else { - this.tag = null; - } - this.isBatch = isBatch; - + this.grayName = grayName; //retry interval: 1s setTaskInterval(1000L); } @@ -52,11 +44,7 @@ public void merge(AbstractDelayTask task) { final String handleIp; - final boolean isBeta; - - final String tag; - - final boolean isBatch; + final String grayName; public String getGroupKey() { return groupKey; @@ -70,16 +58,8 @@ public String getHandleIp() { return handleIp; } - public boolean isBeta() { - return isBeta; - } - - public String getTag() { - return tag; - } - - public boolean isBatch() { - return isBatch; + public String getGrayName() { + return grayName; } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java new file mode 100644 index 00000000000..7982be1582f --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java @@ -0,0 +1,188 @@ +/* + * Copyright 1999-2022 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.repository; + +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.PaginationHelper; + +import java.sql.Timestamp; +import java.util.List; + +/** + * Database service, providing access to config_info_gray in the database. + * + * @author rong + */ +public interface ConfigInfoGrayPersistService { + + /** + * create Pagination utils. + * + * @param Generic object + * @return {@link PaginationHelper} + */ + PaginationHelper createPaginationHelper(); + + //------------------------------------------insert---------------------------------------------// + + + /** + * get gray config info state. + * + * @param dataId dataId. + * @param group group. + * @param tenant tenant. + * @param grayName gray name. + * @return config info state. + */ + ConfigInfoStateWrapper findConfigInfo4GrayState(final String dataId, final String group, final String tenant, + String grayName); + + /** + * Add gray configuration information and publish data change events. + * + * @param configInfo config info + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip + * @param srcUser user + * @return config operation result. + */ + ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser); + + /** + * insert or update gray config. + * + * @param configInfo config info + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip + * @param srcUser user + * @return config operation result. + */ + ConfigOperateResult insertOrUpdateGray(final ConfigInfo configInfo, final String grayName, final String grayRule, + final String srcIp, final String srcUser); + + /** + * insert or update gray config cas. + * + * @param configInfo config info. + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip. + * @param srcUser user. + * @return config operation result. + */ + ConfigOperateResult insertOrUpdateGrayCas(final ConfigInfo configInfo, final String grayName, final String grayRule, + final String srcIp, final String srcUser); + //------------------------------------------delete---------------------------------------------// + + /** + * Delete configuration; database atomic operation, minimum SQL action, no business encapsulation. + * + * @param dataId dataId + * @param group group + * @param tenant tenant + * @param grayName gray name + * @param srcIp remote ip + * @param srcUser user + */ + void removeConfigInfoGray(final String dataId, final String group, final String tenant, final String grayName, + final String srcIp, final String srcUser); + //------------------------------------------update---------------------------------------------// + + /** + * Update gray configuration information. + * + * @param configInfo config info + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip + * @param srcUser user + * @return config operation result. + */ + ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser); + + /** + * Update gray configuration information. + * + * @param configInfo config info + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip + * @param srcUser user + * @return success or not. + */ + ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser); + //------------------------------------------select---------------------------------------------// + + /** + * Query gray configuration information based on dataId and group. + * + * @param dataId data id + * @param group group + * @param tenant tenant + * @param grayName gray name + * @return {@link com.alibaba.nacos.config.server.model.ConfigInfo4Gray} + */ + ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String group, final String tenant, + final String grayName); + + /** + * Returns the number of gray configuration items. + * + * @return number of configuration items. + */ + int configInfoGrayCount(); + + /** + * Query all gray config info for dump task. + * + * @param pageNo page numbser + * @param pageSize page sizxe + * @return {@link Page} with {@link ConfigInfoWrapper} generation + */ + Page findAllConfigInfoGrayForDumpAll(final int pageNo, final int pageSize); + + /** + * Query all gray config info for dump task. + * + * @param startTime startTime + * @param lastMaxId lastMaxId + * @param pageSize pageSize + * @return {@link Page} with {@link ConfigInfoWrapper} generation + */ + List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize); + + /** + * found all config grays. + * + * @param dataId dataId. + * @param group group. + * @param tenant tenant. + * @return + */ + List findConfigInfoGrays(final String dataId, final String group, final String tenant); +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java index 8b45b37905e..62118ed3d97 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java @@ -26,6 +26,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfoBase; import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoChanged; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; @@ -55,6 +56,8 @@ public class ConfigRowMapperInjector { public static final ConfigInfoTagWrapperRowMapper CONFIG_INFO_TAG_WRAPPER_ROW_MAPPER = new ConfigInfoTagWrapperRowMapper(); + public static final ConfigInfoGrayWrapperRowMapper CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER = new ConfigInfoGrayWrapperRowMapper(); + public static final ConfigInfoRowMapper CONFIG_INFO_ROW_MAPPER = new ConfigInfoRowMapper(); public static final ConfigAdvanceInfoRowMapper CONFIG_ADVANCE_INFO_ROW_MAPPER = new ConfigAdvanceInfoRowMapper(); @@ -305,6 +308,39 @@ public ConfigInfoTagWrapper mapRow(ResultSet rs, int rowNum) throws SQLException } } + public static final class ConfigInfoGrayWrapperRowMapper implements RowMapper { + + @Override + public ConfigInfoGrayWrapper mapRow(ResultSet rs, int rowNum) throws SQLException { + ConfigInfoGrayWrapper info = new ConfigInfoGrayWrapper(); + + info.setDataId(rs.getString("data_id")); + info.setGroup(rs.getString("group_id")); + info.setTenant(rs.getString("tenant_id")); + info.setGrayName(rs.getString("gray_name")); + info.setGrayRule(rs.getString("gray_rule")); + info.setAppName(rs.getString("app_name")); + + try { + info.setContent(rs.getString("content")); + } catch (SQLException ignore) { + } + try { + info.setId(rs.getLong("id")); + } catch (SQLException ignore) { + } + try { + info.setLastModified(rs.getTimestamp("gmt_modified").getTime()); + } catch (SQLException ignore) { + } + try { + info.setMd5(rs.getString("md5")); + } catch (SQLException ignore) { + } + return info; + } + } + public static final class ConfigInfoRowMapper implements RowMapper { @Override diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java new file mode 100644 index 00000000000..3a1e952a6a8 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java @@ -0,0 +1,344 @@ +/* + * Copyright 1999-2022 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.repository.embedded; + +import com.alibaba.nacos.common.notify.NotifyCenter; +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils; +import com.alibaba.nacos.config.server.utils.LogUtil; +import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.model.event.DerbyImportEvent; +import com.alibaba.nacos.persistence.repository.PaginationHelper; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedPaginationHelperImpl; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; +import com.alibaba.nacos.plugin.datasource.MapperManager; +import com.alibaba.nacos.plugin.datasource.constants.CommonConstant; +import com.alibaba.nacos.plugin.datasource.constants.FieldConstant; +import com.alibaba.nacos.plugin.datasource.constants.TableConstant; +import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoGrayMapper; +import com.alibaba.nacos.plugin.datasource.model.MapperContext; +import com.alibaba.nacos.plugin.datasource.model.MapperResult; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.springframework.context.annotation.Conditional; +import org.springframework.dao.DataAccessException; +import org.springframework.stereotype.Service; + +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; + +/** + * EmbeddedConfigInfoGrayPersistServiceImpl. + * + * @author rong + */ +@SuppressWarnings({"PMD.MethodReturnWrapperTypeRule", "checkstyle:linelength"}) +@Conditional(value = ConditionOnEmbeddedStorage.class) +@Service("embeddedConfigInfoGrayPersistServiceImpl") +public class EmbeddedConfigInfoGrayPersistServiceImpl implements ConfigInfoGrayPersistService { + + private DataSourceService dataSourceService; + + private final DatabaseOperate databaseOperate; + + private MapperManager mapperManager; + + /** + * The constructor sets the dependency injection order. + * + * @param databaseOperate databaseOperate. + */ + public EmbeddedConfigInfoGrayPersistServiceImpl(DatabaseOperate databaseOperate) { + this.databaseOperate = databaseOperate; + this.dataSourceService = DynamicDataSource.getInstance().getDataSource(); + Boolean isDataSourceLogEnable = EnvUtil.getProperty(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG, Boolean.class, + false); + this.mapperManager = MapperManager.instance(isDataSourceLogEnable); + NotifyCenter.registerToSharePublisher(DerbyImportEvent.class); + } + + @Override + public PaginationHelper createPaginationHelper() { + return new EmbeddedPaginationHelperImpl<>(databaseOperate); + } + + @Override + public ConfigInfoStateWrapper findConfigInfo4GrayState(final String dataId, final String group, final String tenant, + String grayName) { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + + String sql = configInfoGrayMapper.select(Arrays.asList("id", "data_id", "group_id", "tenant_id", "gmt_modified"), + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")); + return databaseOperate.queryOne(sql, new Object[] {dataId, group, tenantTmp, grayNameTmp}, + CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + } + + private ConfigOperateResult getGrayOperateResult(String dataId, String group, String tenant, String grayName) { + String tenantTmp = StringUtils.defaultEmptyIfBlank(tenant); + ConfigInfoStateWrapper configInfo4Gray = this.findConfigInfo4GrayState(dataId, group, tenantTmp, grayName); + if (configInfo4Gray == null) { + return new ConfigOperateResult(false); + } + return new ConfigOperateResult(configInfo4Gray.getId(), configInfo4Gray.getLastModified()); + + } + + @Override + public ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + + configInfo.setTenant(tenantTmp); + + try { + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + final String sql = configInfoGrayMapper.insert( + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", "md5", "src_ip", + "src_user", "gmt_create", "gmt_modified")); + Timestamp time = new Timestamp(System.currentTimeMillis()); + + final Object[] args = new Object[] {configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp, grayRuleTmp, + appNameTmp, configInfo.getContent(), md5, srcIp, srcUser, time, time}; + + EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, time); + EmbeddedStorageContextHolder.addSqlContext(sql, args); + + databaseOperate.blockUpdate(); + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + + } finally { + EmbeddedStorageContextHolder.cleanAllContext(); + } + } + + @Override + public ConfigOperateResult insertOrUpdateGray(final ConfigInfo configInfo, final String grayName, final String grayRule, + final String srcIp, final String srcUser) { + if (findConfigInfo4GrayState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), grayName) == null) { + return addConfigInfo4Gray(configInfo, grayName, grayRule, srcIp, srcUser); + } else { + return updateConfigInfo4Gray(configInfo, grayName, grayRule, srcIp, srcUser); + } + } + + @Override + public ConfigOperateResult insertOrUpdateGrayCas(final ConfigInfo configInfo, final String grayName, final String grayRule, + final String srcIp, final String srcUser) { + if (findConfigInfo4GrayState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), grayName) == null) { + return addConfigInfo4Gray(configInfo, grayName, grayRule, srcIp, srcUser); + } else { + return updateConfigInfo4GrayCas(configInfo, grayName, grayRule, srcIp, srcUser); + } + } + + @Override + public void removeConfigInfoGray(final String dataId, final String group, final String tenant, final String grayName, + final String srcIp, final String srcUser) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName; + + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + final String sql = configInfoGrayMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")); + final Object[] args = new Object[] {dataId, group, tenantTmp, grayNameTmp}; + + EmbeddedStorageContextUtils.onDeleteConfigGrayInfo(tenantTmp, group, dataId, grayNameTmp, srcIp); + EmbeddedStorageContextHolder.addSqlContext(sql, args); + try { + databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); + } finally { + EmbeddedStorageContextHolder.cleanAllContext(); + } + } + + @Override + public ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + + configInfo.setTenant(tenantTmp); + + try { + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + Timestamp time = new Timestamp(System.currentTimeMillis()); + + final String sql = configInfoGrayMapper.update( + Arrays.asList("content", "md5", "src_ip", "src_user", "gmt_modified", "app_name", "gray_rule"), + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")); + final Object[] args = new Object[] {configInfo.getContent(), md5, srcIp, srcUser, time, appNameTmp, + grayRuleTmp, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp}; + + EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, time); + EmbeddedStorageContextHolder.addSqlContext(sql, args); + + databaseOperate.blockUpdate(); + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + + } finally { + EmbeddedStorageContextHolder.cleanAllContext(); + } + } + + @Override + public ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + + configInfo.setTenant(tenantTmp); + + try { + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + Timestamp time = new Timestamp(System.currentTimeMillis()); + + MapperContext context = new MapperContext(); + context.putUpdateParameter(FieldConstant.CONTENT, configInfo.getContent()); + context.putUpdateParameter(FieldConstant.MD5, md5); + context.putUpdateParameter(FieldConstant.SRC_IP, srcIp); + context.putUpdateParameter(FieldConstant.SRC_USER, srcUser); + context.putUpdateParameter(FieldConstant.GMT_MODIFIED, time); + context.putUpdateParameter(FieldConstant.APP_NAME, appNameTmp); + + context.putWhereParameter(FieldConstant.DATA_ID, configInfo.getDataId()); + context.putWhereParameter(FieldConstant.GROUP_ID, configInfo.getGroup()); + context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); + context.putWhereParameter(FieldConstant.GRAY_NAME, grayNameTmp); + context.putWhereParameter(FieldConstant.GRAY_RULE, grayRuleTmp); + context.putWhereParameter(FieldConstant.MD5, configInfo.getMd5()); + + final MapperResult mapperResult = configInfoGrayMapper.updateConfigInfo4GrayCas(context); + + EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, time); + EmbeddedStorageContextHolder.addSqlContext(mapperResult.getSql(), mapperResult.getParamList().toArray()); + + Boolean success = databaseOperate.blockUpdate(); + if (success) { + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + } else { + return new ConfigOperateResult(false); + } + + } finally { + EmbeddedStorageContextHolder.cleanAllContext(); + } + } + + @Override + public ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String group, final String tenant, + final String grayName) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + final String sql = configInfoGrayMapper.select( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", + "gmt_modified"), Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")); + + return databaseOperate.queryOne(sql, new Object[] {dataId, group, tenantTmp, grayNameTmp}, + CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + } + + @Override + public int configInfoGrayCount() { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String sql = configInfoGrayMapper.count(null); + Integer result = databaseOperate.queryOne(sql, Integer.class); + if (result == null) { + throw new IllegalArgumentException("configInfoBetaCount error"); + } + return result; + } + + @Override + public Page findAllConfigInfoGrayForDumpAll(final int pageNo, final int pageSize) { + final int startRow = (pageNo - 1) * pageSize; + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String sqlCountRows = configInfoGrayMapper.count(null); + MapperResult sqlFetchRows = configInfoGrayMapper.findAllConfigInfoGrayForDumpAllFetchRows( + new MapperContext(startRow, pageSize)); + + PaginationHelper helper = createPaginationHelper(); + return helper.fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), pageNo, + pageSize, CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + + } + + @Override + public List findConfigInfoGrays(String dataId, String group, String tenant) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + final String sql = configInfoGrayMapper.select(Collections.singletonList("gray_name"), + Arrays.asList("data_id", "group_id", "tenant_id")); + + return databaseOperate.queryMany(sql, new Object[] {dataId, group, tenantTmp}, String.class); + } + + @Override + public List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize) { + try { + ConfigInfoGrayMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + + MapperContext context = new MapperContext(); + context.putWhereParameter(FieldConstant.START_TIME, startTime); + context.putWhereParameter(FieldConstant.PAGE_SIZE, pageSize); + context.putWhereParameter(FieldConstant.LAST_MAX_ID, lastMaxId); + + MapperResult mapperResult = configInfoMapper.findChangeConfig(context); + return databaseOperate.queryMany(mapperResult.getSql(), mapperResult.getParamList().toArray(), + CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + } catch (DataAccessException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java new file mode 100644 index 00000000000..0a3caf58445 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java @@ -0,0 +1,330 @@ +/* + * Copyright 1999-2022 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.repository.extrnal; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.utils.LogUtil; +import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.PaginationHelper; +import com.alibaba.nacos.persistence.repository.extrnal.ExternalStoragePaginationHelperImpl; +import com.alibaba.nacos.plugin.datasource.MapperManager; +import com.alibaba.nacos.plugin.datasource.constants.CommonConstant; +import com.alibaba.nacos.plugin.datasource.constants.FieldConstant; +import com.alibaba.nacos.plugin.datasource.constants.TableConstant; +import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoGrayMapper; +import com.alibaba.nacos.plugin.datasource.model.MapperContext; +import com.alibaba.nacos.plugin.datasource.model.MapperResult; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.springframework.context.annotation.Conditional; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; +import org.springframework.transaction.support.TransactionTemplate; + +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; + + +/** + * ExternalConfigInfoGrayPersistServiceImpl. + * + * @author rong + */ +@SuppressWarnings(value = {"PMD.MethodReturnWrapperTypeRule", "checkstyle:linelength"}) +@Conditional(value = ConditionOnExternalStorage.class) +@Service("externalConfigInfoGrayPersistServiceImpl") +public class ExternalConfigInfoGrayPersistServiceImpl implements ConfigInfoGrayPersistService { + + private DataSourceService dataSourceService; + + protected JdbcTemplate jt; + + protected TransactionTemplate tjt; + + private MapperManager mapperManager; + + public ExternalConfigInfoGrayPersistServiceImpl() { + this.dataSourceService = DynamicDataSource.getInstance().getDataSource(); + this.jt = dataSourceService.getJdbcTemplate(); + this.tjt = dataSourceService.getTransactionTemplate(); + Boolean isDataSourceLogEnable = EnvUtil.getProperty(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG, Boolean.class, + false); + this.mapperManager = MapperManager.instance(isDataSourceLogEnable); + } + + @Override + public PaginationHelper createPaginationHelper() { + return new ExternalStoragePaginationHelperImpl<>(jt); + } + + @Override + public ConfigInfoStateWrapper findConfigInfo4GrayState(final String dataId, final String group, final String tenant, + String grayName) { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + try { + return this.jt.queryForObject(configInfoGrayMapper.select( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "gray_rule", "gmt_modified"), + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + new Object[] {dataId, group, tenantTmp, grayNameTmp}, CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + } catch (EmptyResultDataAccessException e) { + return null; + } + } + + private ConfigOperateResult getGrayOperateResult(String dataId, String group, String tenant, String grayName) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + + ConfigInfoStateWrapper configInfo4Gray = this.findConfigInfo4GrayState(dataId, group, tenantTmp, grayName); + if (configInfo4Gray == null) { + return new ConfigOperateResult(false); + } + return new ConfigOperateResult(configInfo4Gray.getId(), configInfo4Gray.getLastModified()); + + } + + @Override + public ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, + String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + try { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + jt.update(configInfoGrayMapper.insert( + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", + "encrypted_data_key", "md5", "src_ip", "src_user", "gmt_create@NOW()", "gmt_modified@NOW()")), + configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp, grayRuleTmp, appNameTmp, + configInfo.getContent(), configInfo.getEncryptedDataKey(), md5, srcIp, srcUser); + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public ConfigOperateResult insertOrUpdateGray(final ConfigInfo configInfo, final String grayName, + final String grayRule, final String srcIp, final String srcUser) { + if (findConfigInfo4GrayState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), grayName) + == null) { + return addConfigInfo4Gray(configInfo, grayName, grayRule, srcIp, srcUser); + } else { + return updateConfigInfo4Gray(configInfo, grayName, grayRule, srcIp, srcUser); + } + } + + @Override + public ConfigOperateResult insertOrUpdateGrayCas(final ConfigInfo configInfo, final String grayName, + final String grayRule, final String srcIp, final String srcUser) { + if (findConfigInfo4GrayState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), grayName) + == null) { + return addConfigInfo4Gray(configInfo, grayName, grayRule, srcIp, srcUser); + } else { + return updateConfigInfo4GrayCas(configInfo, grayName, grayRule, srcIp, srcUser); + } + } + + @Override + public void removeConfigInfoGray(final String dataId, final String group, final String tenant, + final String grayName, final String srcIp, final String srcUser) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName; + try { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + jt.update(configInfoGrayMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + dataId, group, tenantTmp, grayNameTmp); + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + try { + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + jt.update(configInfoGrayMapper.update( + Arrays.asList("content", "encrypted_data_key", "md5", "src_ip", "src_user", "gmt_modified@NOW()", + "app_name", "gray_rule"), Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + configInfo.getContent(), configInfo.getEncryptedDataKey(), md5, srcIp, srcUser, appNameTmp, + grayRuleTmp, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + try { + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + Timestamp time = new Timestamp(System.currentTimeMillis()); + + MapperContext context = new MapperContext(); + context.putUpdateParameter(FieldConstant.CONTENT, configInfo.getContent()); + context.putUpdateParameter(FieldConstant.MD5, md5); + context.putUpdateParameter(FieldConstant.SRC_IP, srcIp); + context.putUpdateParameter(FieldConstant.SRC_USER, srcUser); + context.putUpdateParameter(FieldConstant.APP_NAME, appNameTmp); + + context.putWhereParameter(FieldConstant.DATA_ID, configInfo.getDataId()); + context.putWhereParameter(FieldConstant.GROUP_ID, configInfo.getGroup()); + context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); + context.putWhereParameter(FieldConstant.GRAY_NAME, grayNameTmp); + context.putWhereParameter(FieldConstant.GRAY_RULE, grayRuleTmp); + context.putWhereParameter(FieldConstant.MD5, configInfo.getMd5()); + + final MapperResult mapperResult = configInfoGrayMapper.updateConfigInfo4GrayCas(context); + + boolean success = jt.update(mapperResult.getSql(), mapperResult.getParamList().toArray()) > 0; + if (success) { + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + } else { + return new ConfigOperateResult(false); + } + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String group, final String tenant, + final String grayName) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + try { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + return this.jt.queryForObject(configInfoGrayMapper.select( + Arrays.asList("id", "md5", "data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", + "content", "encrypted_data_key", "gmt_modified"), + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + new Object[] {dataId, group, tenantTmp, grayNameTmp}, CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. + return null; + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public int configInfoGrayCount() { + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String sql = configInfoGrayMapper.count(null); + Integer result = jt.queryForObject(sql, Integer.class); + if (result == null) { + throw new IllegalArgumentException("configInfoGrayCount error"); + } + return result; + } + + @Override + public Page findAllConfigInfoGrayForDumpAll(final int pageNo, final int pageSize) { + final int startRow = (pageNo - 1) * pageSize; + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String sqlCountRows = configInfoGrayMapper.count(null); + MapperResult sqlFetchRows = configInfoGrayMapper.findAllConfigInfoGrayForDumpAllFetchRows( + new MapperContext(startRow, pageSize)); + + PaginationHelper helper = createPaginationHelper(); + + try { + return helper.fetchPageLimit(sqlCountRows, sqlFetchRows.getSql(), sqlFetchRows.getParamList().toArray(), + pageNo, pageSize, CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize) { + try { + ConfigInfoGrayMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + + MapperContext context = new MapperContext(); + context.putWhereParameter(FieldConstant.START_TIME, startTime); + context.putWhereParameter(FieldConstant.PAGE_SIZE, pageSize); + context.putWhereParameter(FieldConstant.LAST_MAX_ID, lastMaxId); + + MapperResult mapperResult = configInfoMapper.findChangeConfig(context); + return jt.query(mapperResult.getSql(), mapperResult.getParamList().toArray(), + CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + } catch (DataAccessException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + + @Override + public List findConfigInfoGrays(final String dataId, final String group, final String tenant) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + String selectSql = configInfoGrayMapper.select(Collections.singletonList("gray_name"), + Arrays.asList("data_id", "group_id", "tenant_id")); + return jt.queryForList(selectSql, new Object[] {dataId, group, tenantTmp}, String.class); + } + +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java b/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java index dac6777617f..1190a91ef80 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java @@ -102,6 +102,29 @@ public static void onModifyConfigTagInfo(ConfigInfo configInfo, String tag, Stri } } + /** + * In the case of the in-cluster storage mode, the logic of horizontal notification is implemented asynchronously + * via the raft state machine, along with the information. + * + * @param configInfo {@link ConfigInfo} + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp The IP of the operator + * @param time Operating time + */ + public static void onModifyConfigGrayInfo(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, Timestamp time) { + if (!EnvUtil.getStandaloneMode()) { + ConfigDumpEvent event = ConfigDumpEvent.builder().remove(false).namespaceId(configInfo.getTenant()) + .dataId(configInfo.getDataId()).group(configInfo.getGroup()).isBeta(false).grayName(grayName) + .grayRule(grayRule).content(configInfo.getContent()).type(configInfo.getType()).handleIp(srcIp) + .lastModifiedTs(time.getTime()).build(); + + Map extendInfo = new HashMap<>(2); + extendInfo.put(Constants.EXTEND_INFO_CONFIG_DUMP_EVENT, JacksonUtils.toJson(event)); + EmbeddedStorageContextHolder.putAllExtendInfo(extendInfo); + } + } + /** * In the case of the in-cluster storage mode, the logic of horizontal notification is implemented asynchronously * via the raft state machine, along with the information. @@ -190,4 +213,25 @@ public static void onDeleteConfigTagInfo(String namespaceId, String group, Strin } } + /** + * In the case of the in-cluster storage mode, the logic of horizontal notification is implemented asynchronously + * via the raft state machine, along with the information. + * + * @param namespaceId namespaceId + * @param group group + * @param dataId dataId + * @param grayName gray name + * @param srcIp The IP of the operator + */ + public static void onDeleteConfigGrayInfo(String namespaceId, String group, String dataId, String grayName, + String srcIp) { + if (!EnvUtil.getStandaloneMode()) { + ConfigDumpEvent event = ConfigDumpEvent.builder().remove(true).namespaceId(namespaceId).group(group) + .dataId(dataId).isBeta(true).grayName(grayName).handleIp(srcIp).build(); + + Map extendInfo = new HashMap<>(2); + extendInfo.put(Constants.EXTEND_INFO_CONFIG_DUMP_EVENT, JacksonUtils.toJson(event)); + EmbeddedStorageContextHolder.putAllExtendInfo(extendInfo); + } + } } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/trace/ConfigTraceService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/trace/ConfigTraceService.java index ec9b4a58fcc..5133e14c478 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/trace/ConfigTraceService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/trace/ConfigTraceService.java @@ -41,8 +41,6 @@ public class ConfigTraceService { public static final String PERSISTENCE_EVENT_BETA = "persist-beta"; - public static final String PERSISTENCE_EVENT_BATCH = "persist-batch"; - public static final String PERSISTENCE_EVENT_TAG = "persist-tag"; /** @@ -101,12 +99,6 @@ public class ConfigTraceService { */ public static final String PULL_EVENT = "pull"; - public static final String PULL_EVENT_BETA = "pull-beta"; - - public static final String PULL_EVENT_BATCH = "pull-batch"; - - public static final String PULL_EVENT_TAG = "pull-tag"; - /** * pull type. */ @@ -197,22 +189,10 @@ public static void logDumpEvent(String dataId, String group, String tenant, Stri delayed, length); } - public static void logDumpBetaEvent(String dataId, String group, String tenant, String requestIpAppName, long ts, - String handleIp, String type, long delayed, long length) { - logDumpEventInner(dataId, group, tenant, requestIpAppName, ts, handleIp, ConfigTraceService.DUMP_EVENT_BETA, - type, delayed, length); - } - - public static void logDumpBatchEvent(String dataId, String group, String tenant, String requestIpAppName, long ts, - String handleIp, String type, long delayed, long length) { - logDumpEventInner(dataId, group, tenant, requestIpAppName, ts, handleIp, ConfigTraceService.DUMP_EVENT_BATCH, - type, delayed, length); - } - - public static void logDumpTagEvent(String dataId, String group, String tenant, String tag, String requestIpAppName, - long ts, String handleIp, String type, long delayed, long length) { + public static void logDumpGrayNameEvent(String dataId, String group, String tenant, String grayName, + String requestIpAppName, long ts, String handleIp, String type, long delayed, long length) { logDumpEventInner(dataId, group, tenant, requestIpAppName, ts, handleIp, - ConfigTraceService.DUMP_EVENT_TAG + "-" + tag, type, delayed, length); + ConfigTraceService.DUMP_EVENT + "-" + grayName, type, delayed, length); } private static void logDumpEventInner(String dataId, String group, String tenant, String requestIpAppName, long ts, diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/MD5Util.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/MD5Util.java index c0633c2061f..9d9faa84a91 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/MD5Util.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/MD5Util.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Map; +import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG; import static com.alibaba.nacos.config.server.constant.Constants.LINE_SEPARATOR; import static com.alibaba.nacos.config.server.constant.Constants.WORD_SEPARATOR; @@ -52,7 +53,7 @@ public class MD5Util { public static List compareMd5(HttpServletRequest request, HttpServletResponse response, Map clientMd5Map) { List changedGroupKeys = new ArrayList<>(); - String tag = request.getHeader("Vipserver-Tag"); + String tag = request.getHeader(VIPSERVER_TAG); for (Map.Entry entry : clientMd5Map.entrySet()) { String groupKey = entry.getKey(); String clientMd5 = entry.getValue(); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/PropertyUtil.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/PropertyUtil.java index 4c8e79df848..33ce7f8eb5c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/utils/PropertyUtil.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/PropertyUtil.java @@ -53,6 +53,11 @@ public class PropertyUtil implements ApplicationContextInitializer subscribeType() { } }); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete(Constants.CONFIG_CONTROLLER_PATH).param("delType", "ids") - .param("ids", "1,2"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete(Constants.CONFIG_CONTROLLER_PATH) + .param("delType", "ids").param("ids", "1,2"); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); @@ -224,8 +231,9 @@ void testGetConfigAdvanceInfo() throws Exception { when(configInfoPersistService.findConfigAdvanceInfo("test", "test", "")).thenReturn(configAdvanceInfo); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH + "/catalog") - .param("dataId", "test").param("group", "test").param("tenant", ""); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get( + Constants.CONFIG_CONTROLLER_PATH + "/catalog").param("dataId", "test").param("group", "test") + .param("tenant", ""); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); String code = JacksonUtils.toObj(actualValue).get("code").toString(); @@ -240,8 +248,8 @@ void testGetConfigAdvanceInfo() throws Exception { @Test void testListener() throws Exception { - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post(Constants.CONFIG_CONTROLLER_PATH + "/listener") - .param("Listening-Configs", "test"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post( + Constants.CONFIG_CONTROLLER_PATH + "/listener").param("Listening-Configs", "test"); int actualValue = mockmvc.perform(builder).andReturn().getResponse().getStatus(); assertEquals(200, actualValue); } @@ -255,11 +263,13 @@ void testGetListeners() throws Exception { when(configSubService.getCollectSampleResult("test", "test", "", 1)).thenReturn(sampleResult); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH + "/listener") - .param("dataId", "test").param("group", "test").param("tenant", "").param("sampleTime", "1"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get( + Constants.CONFIG_CONTROLLER_PATH + "/listener").param("dataId", "test").param("group", "test") + .param("tenant", "").param("sampleTime", "1"); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); - GroupkeyListenserStatus groupkeyListenserStatus = JacksonUtils.toObj(actualValue, GroupkeyListenserStatus.class); + GroupkeyListenserStatus groupkeyListenserStatus = JacksonUtils.toObj(actualValue, + GroupkeyListenserStatus.class); assertEquals(200, groupkeyListenserStatus.getCollectStatus()); assertEquals(1, groupkeyListenserStatus.getLisentersGroupkeyStatus().size()); assertEquals("test", groupkeyListenserStatus.getLisentersGroupkeyStatus().get("test")); @@ -278,11 +288,12 @@ void testSearchConfig() throws Exception { page.setPageItems(configInfoList); Map configAdvanceInfo = new HashMap<>(8); - when(configInfoPersistService.findConfigInfo4Page(1, 10, "test", "test", "", configAdvanceInfo)).thenReturn(page); + when(configInfoPersistService.findConfigInfo4Page(1, 10, "test", "test", "", configAdvanceInfo)).thenReturn( + page); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH).param("search", "accurate") - .param("dataId", "test").param("group", "test").param("appName", "").param("tenant", "").param("config_tags", "") - .param("pageNo", "1").param("pageSize", "10"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH) + .param("search", "accurate").param("dataId", "test").param("group", "test").param("appName", "") + .param("tenant", "").param("config_tags", "").param("pageNo", "1").param("pageSize", "10"); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); @@ -310,16 +321,18 @@ void testFuzzySearchConfig() throws Exception { page.setPageItems(configInfoList); Map configAdvanceInfo = new HashMap<>(8); - when(configInfoPersistService.findConfigInfoLike4Page(1, 10, "test", "test", "", configAdvanceInfo)).thenReturn(page); + when(configInfoPersistService.findConfigInfoLike4Page(1, 10, "test", "test", "", configAdvanceInfo)).thenReturn( + page); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH).param("search", "blur") - .param("dataId", "test").param("group", "test").param("appName", "").param("tenant", "").param("config_tags", "") - .param("pageNo", "1").param("pageSize", "10"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH) + .param("search", "blur").param("dataId", "test").param("group", "test").param("appName", "") + .param("tenant", "").param("config_tags", "").param("pageNo", "1").param("pageSize", "10"); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); List resultList = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("pageItems").toString(), List.class); - ConfigInfo resConfigInfo = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("pageItems").get(0).toString(), ConfigInfo.class); + ConfigInfo resConfigInfo = JacksonUtils.toObj( + JacksonUtils.toObj(actualValue).get("pageItems").get(0).toString(), ConfigInfo.class); assertEquals(configInfoList.size(), resultList.size()); assertEquals(configInfo.getDataId(), resConfigInfo.getDataId()); @@ -330,8 +343,8 @@ void testFuzzySearchConfig() throws Exception { @Test void testStopBeta() throws Exception { - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete(Constants.CONFIG_CONTROLLER_PATH).param("beta", "true") - .param("dataId", "test").param("group", "test").param("tenant", ""); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.delete(Constants.CONFIG_CONTROLLER_PATH) + .param("beta", "true").param("dataId", "test").param("group", "test").param("tenant", ""); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); @@ -344,15 +357,17 @@ void testStopBeta() throws Exception { @Test void testQueryBeta() throws Exception { - ConfigInfoBetaWrapper configInfoBetaWrapper = new ConfigInfoBetaWrapper(); + ConfigInfoGrayWrapper configInfoBetaWrapper = new ConfigInfoGrayWrapper(); configInfoBetaWrapper.setDataId("test"); configInfoBetaWrapper.setGroup("test"); configInfoBetaWrapper.setContent("test"); + configInfoBetaWrapper.setGrayName("beta"); + configInfoBetaWrapper.setGrayRule("{\"type\":\"beta\",\"version\":\"1.0.0\",\"expr\":\"127.0.0.1,127.0.0.2\",\"priority\":-1000}"); + when(configInfoGrayPersistService.findConfigInfo4Gray("test", "test", "", "beta")).thenReturn( + configInfoBetaWrapper); - when(configInfoBetaPersistService.findConfigInfo4Beta("test", "test", "")).thenReturn(configInfoBetaWrapper); - - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH).param("beta", "true") - .param("dataId", "test").param("group", "test").param("tenant", ""); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH) + .param("beta", "true").param("dataId", "test").param("group", "test").param("tenant", ""); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); String code = JacksonUtils.toObj(actualValue).get("code").toString(); @@ -363,6 +378,8 @@ void testQueryBeta() throws Exception { assertEquals(configInfoBetaWrapper.getDataId(), resConfigInfoBetaWrapper.getDataId()); assertEquals(configInfoBetaWrapper.getGroup(), resConfigInfoBetaWrapper.getGroup()); assertEquals(configInfoBetaWrapper.getContent(), resConfigInfoBetaWrapper.getContent()); + assertEquals("127.0.0.1,127.0.0.2", resConfigInfoBetaWrapper.getBetaIps()); + } @Test @@ -383,8 +400,9 @@ void testExportConfig() throws Exception { Mockito.when(configInfoPersistService.findAllConfigInfo4Export(eq(dataId), eq(group), eq(tenant), eq(appname), eq(Arrays.asList(1L, 2L)))).thenReturn(dataList); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH).param("export", "true") - .param("dataId", dataId).param("group", group).param("tenant", tenant).param("appName", appname).param("ids", "1,2"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH) + .param("export", "true").param("dataId", dataId).param("group", group).param("tenant", tenant) + .param("appName", appname).param("ids", "1,2"); int actualValue = mockmvc.perform(builder).andReturn().getResponse().getStatus(); @@ -407,8 +425,9 @@ void testExportConfigV2() throws Exception { dataList.add(configAllInfo); Mockito.when(configInfoPersistService.findAllConfigInfo4Export(eq(dataId), eq(group), eq(tenant), eq(appname), eq(Arrays.asList(1L, 2L)))).thenReturn(dataList); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH).param("exportV2", "true") - .param("dataId", dataId).param("group", group).param("tenant", tenant).param("appName", appname).param("ids", "1,2"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.get(Constants.CONFIG_CONTROLLER_PATH) + .param("exportV2", "true").param("dataId", dataId).param("group", group).param("tenant", tenant) + .param("appName", appname).param("ids", "1,2"); int actualValue = mockmvc.perform(builder).andReturn().getResponse().getStatus(); @@ -428,16 +447,19 @@ void testImportAndPublishConfig() throws Exception { when(namespacePersistService.tenantInfoCountByTenantId("public")).thenReturn(1); Map map = new HashMap<>(); map.put("test", "test"); - when(configInfoPersistService.batchInsertOrUpdate(anyList(), anyString(), anyString(), any(), any())).thenReturn(map); + when(configInfoPersistService.batchInsertOrUpdate(anyList(), anyString(), anyString(), any(), + any())).thenReturn(map); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(Constants.CONFIG_CONTROLLER_PATH).file(file) - .param("import", "true").param("src_user", "test").param("namespace", "public").param("policy", "ABORT"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(Constants.CONFIG_CONTROLLER_PATH) + .file(file).param("import", "true").param("src_user", "test").param("namespace", "public") + .param("policy", "ABORT"); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); String code = JacksonUtils.toObj(actualValue).get("code").toString(); assertEquals("200", code); - Map resultMap = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("data").toString(), Map.class); + Map resultMap = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("data").toString(), + Map.class); assertEquals(map.get("test"), resultMap.get("test").toString()); zipUtilsMockedStatic.close(); @@ -467,16 +489,19 @@ void testImportAndPublishConfigV2() throws Exception { when(namespacePersistService.tenantInfoCountByTenantId("public")).thenReturn(1); Map map = new HashMap<>(); map.put("test", "test"); - when(configInfoPersistService.batchInsertOrUpdate(anyList(), anyString(), anyString(), any(), any())).thenReturn(map); + when(configInfoPersistService.batchInsertOrUpdate(anyList(), anyString(), anyString(), any(), + any())).thenReturn(map); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(Constants.CONFIG_CONTROLLER_PATH).file(file) - .param("import", "true").param("src_user", "test").param("namespace", "public").param("policy", "ABORT"); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.multipart(Constants.CONFIG_CONTROLLER_PATH) + .file(file).param("import", "true").param("src_user", "test").param("namespace", "public") + .param("policy", "ABORT"); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); String code = JacksonUtils.toObj(actualValue).get("code").toString(); assertEquals("200", code); - Map resultMap = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("data").toString(), Map.class); + Map resultMap = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("data").toString(), + Map.class); assertEquals(map.get("test"), resultMap.get("test").toString()); zipUtilsMockedStatic.close(); @@ -502,21 +527,24 @@ void testCloneConfig() throws Exception { List idList = new ArrayList<>(configBeansList.size()); idList.add(sameNamespaceCloneConfigBean.getCfgId()); - when(configInfoPersistService.findAllConfigInfo4Export(null, null, null, null, idList)).thenReturn(queryedDataList); + when(configInfoPersistService.findAllConfigInfo4Export(null, null, null, null, idList)).thenReturn( + queryedDataList); Map map = new HashMap<>(); map.put("test", "test"); - when(configInfoPersistService.batchInsertOrUpdate(anyList(), anyString(), anyString(), any(), any())).thenReturn(map); + when(configInfoPersistService.batchInsertOrUpdate(anyList(), anyString(), anyString(), any(), + any())).thenReturn(map); - MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post(Constants.CONFIG_CONTROLLER_PATH).param("clone", "true") - .param("src_user", "test").param("tenant", "public").param("policy", "ABORT").content(JacksonUtils.toJson(configBeansList)) - .contentType(MediaType.APPLICATION_JSON); + MockHttpServletRequestBuilder builder = MockMvcRequestBuilders.post(Constants.CONFIG_CONTROLLER_PATH) + .param("clone", "true").param("src_user", "test").param("tenant", "public").param("policy", "ABORT") + .content(JacksonUtils.toJson(configBeansList)).contentType(MediaType.APPLICATION_JSON); String actualValue = mockmvc.perform(builder).andReturn().getResponse().getContentAsString(); String code = JacksonUtils.toObj(actualValue).get("code").toString(); assertEquals("200", code); - Map resultMap = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("data").toString(), Map.class); + Map resultMap = JacksonUtils.toObj(JacksonUtils.toObj(actualValue).get("data").toString(), + Map.class); assertEquals(map.get("test"), resultMap.get("test").toString()); } } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigServletInnerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigServletInnerTest.java index 115c39abe2a..651ca61fb84 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigServletInnerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigServletInnerTest.java @@ -20,8 +20,14 @@ import com.alibaba.nacos.common.constant.HttpHeaderConsts; import com.alibaba.nacos.common.http.param.MediaType; import com.alibaba.nacos.common.utils.JacksonUtils; +import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.CacheItem; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.ConfigGrayPersistInfo; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.LongPollingService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; @@ -54,6 +60,8 @@ import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG; import static com.alibaba.nacos.config.server.constant.Constants.CONTENT_MD5; +import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_GBK; +import static com.alibaba.nacos.config.server.constant.Constants.ENCODE_UTF8; import static com.alibaba.nacos.config.server.utils.RequestUtil.CLIENT_APPNAME_HEADER; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -143,33 +151,55 @@ void testDoGetConfigV1Beta() throws Exception { //mock cache item isBeta CacheItem cacheItem = new CacheItem("test"); - cacheItem.setBeta(true); - List ips4Beta = new ArrayList<>(); - ips4Beta.add("localhost"); - cacheItem.setIps4Beta(ips4Beta); - cacheItem.initBetaCacheIfEmpty(); - cacheItem.getConfigCacheBeta().setEncryptedDataKey("betaKey1234567"); - cacheItem.getConfigCacheBeta().setMd5Utf8("md52345Beta"); String dataId = "testDataId135"; String group = "group23"; String tenant = "tenant234"; - configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataId, group, tenant))) + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataId, group, tenant))) .thenReturn(cacheItem); - + String mockBetaContent = "content3456543"; + mockGray4Beta(cacheItem, mockBetaContent, "localhost", "betaKey1234567"); MockHttpServletRequest request = new MockHttpServletRequest(); request.setRemoteAddr("localhost:8080"); request.addHeader(CLIENT_APPNAME_HEADER, "test"); MockHttpServletResponse response = new MockHttpServletResponse(); - String mockBetaContent = "content3456543"; - when(configRocksDbDiskService.getBetaContent(dataId, group, tenant)).thenReturn(mockBetaContent); - String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, "", "true", "localhost"); + + when(configRocksDbDiskService.getGrayContent(dataId, group, tenant, BetaGrayRule.TYPE_BETA)).thenReturn( + mockBetaContent); + String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, "", "true", + "localhost"); assertEquals(HttpServletResponse.SC_OK + "", actualValue); assertEquals("true", response.getHeader("isBeta")); - assertEquals("md52345Beta", response.getHeader(CONTENT_MD5)); + assertEquals(MD5Utils.md5Hex(mockBetaContent, ENCODE_UTF8), response.getHeader(CONTENT_MD5)); assertEquals("betaKey1234567", response.getHeader("Encrypted-Data-Key")); assertEquals(mockBetaContent, response.getContentAsString()); } + private void mockGray4Beta(CacheItem cacheItem, String content, String betaIps, String dataKey) { + cacheItem.initConfigGrayIfEmpty(BetaGrayRule.TYPE_BETA); + ConfigCacheGray configCacheGray = cacheItem.getConfigCacheGray().get(BetaGrayRule.TYPE_BETA); + configCacheGray.setMd5Utf8(MD5Utils.md5Hex(content, ENCODE_UTF8)); + configCacheGray.setMd5Gbk(MD5Utils.md5Hex(content, ENCODE_GBK)); + configCacheGray.setEncryptedDataKey(dataKey); + ConfigGrayPersistInfo configGrayPersistInfo = new ConfigGrayPersistInfo(BetaGrayRule.TYPE_BETA, + BetaGrayRule.VERSION, betaIps, -1000); + configCacheGray.resetGrayRule(GrayRuleManager.serializeConfigGrayPersistInfo(configGrayPersistInfo)); + cacheItem.sortConfigGray(); + } + + private void mockGray4Tag(CacheItem cacheItem, String content, String tagValue, String dataKey, long ts) { + cacheItem.initConfigGrayIfEmpty(TagGrayRule.TYPE_TAG + "_" + tagValue); + ConfigCacheGray configCacheGray = cacheItem.getConfigCacheGray().get(TagGrayRule.TYPE_TAG + "_" + tagValue); + configCacheGray.setMd5Utf8(MD5Utils.md5Hex(content, ENCODE_UTF8)); + configCacheGray.setMd5Gbk(MD5Utils.md5Hex(content, ENCODE_GBK)); + configCacheGray.setLastModifiedTs(ts); + configCacheGray.setEncryptedDataKey(dataKey); + ConfigGrayPersistInfo configGrayPersistInfo = new ConfigGrayPersistInfo(TagGrayRule.TYPE_TAG, + TagGrayRule.VERSION, tagValue, -999); + configCacheGray.resetGrayRule(GrayRuleManager.serializeConfigGrayPersistInfo(configGrayPersistInfo)); + cacheItem.sortConfigGray(); + } + /** * test get config of tag. * @@ -181,29 +211,23 @@ void testDoGetConfigV1Tag() throws Exception { String dataId = "dataId123455"; String group = "group"; String tenant = "tenant"; - configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))) - .thenReturn(1); + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))).thenReturn(1); //mock cache item with tag. CacheItem cacheItem = new CacheItem("test"); - cacheItem.setBeta(false); - List ips4Beta = new ArrayList<>(); - ips4Beta.add("localhost"); - cacheItem.setIps4Beta(ips4Beta); String autoTag = "auto-tag-test"; - cacheItem.initConfigTagsIfEmpty(autoTag); - cacheItem.getConfigCacheTags().get(autoTag).setEncryptedDataKey("autoTagkey"); - cacheItem.getConfigCacheTags().get(autoTag).setMd5Utf8("md5autotag11"); long autoTagTs = System.currentTimeMillis(); - cacheItem.getConfigCacheTags().get(autoTag).setLastModifiedTs(autoTagTs); + String autoTagContent = "1234566autotag"; + mockGray4Tag(cacheItem, autoTagContent, autoTag, "autoTagkey", autoTagTs); + String specificTag = "specificTag"; - cacheItem.initConfigTagsIfEmpty(specificTag); - cacheItem.getConfigCacheTags().get(specificTag).setEncryptedDataKey("specificTagkey"); - cacheItem.getConfigCacheTags().get(specificTag).setMd5Utf8("md5specificTag11"); + String specificTagContent = "1234566autotag"; long specificTs = System.currentTimeMillis(); - cacheItem.getConfigCacheTags().get(specificTag).setLastModifiedTs(specificTs); + mockGray4Tag(cacheItem, specificTagContent, specificTag, "specificTagkey", specificTs); - configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(GroupKey2.getKey(dataId, group, tenant))) + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.getContentCache(GroupKey2.getKey(dataId, group, tenant))) .thenReturn(cacheItem); //test auto tag. @@ -212,29 +236,34 @@ void testDoGetConfigV1Tag() throws Exception { request.addHeader(CLIENT_APPNAME_HEADER, "test"); request.addHeader(VIPSERVER_TAG, autoTag); MockHttpServletResponse response = new MockHttpServletResponse(); - String autoTagContent = "1234566autotag"; - Mockito.when(configRocksDbDiskService.getTagContent(dataId, group, tenant, autoTag)).thenReturn(autoTagContent); - String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, null, "true", "localhost"); + + Mockito.when( + configRocksDbDiskService.getGrayContent(dataId, group, tenant, TagGrayRule.TYPE_TAG + "_" + autoTag)) + .thenReturn(autoTagContent); + String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, null, "true", + "localhost"); assertEquals(HttpServletResponse.SC_OK + "", actualValue); assertEquals(autoTagContent, response.getContentAsString()); - assertEquals("md5autotag11", response.getHeader(CONTENT_MD5)); + assertEquals(MD5Utils.md5Hex(autoTagContent, "UTF-8"), response.getHeader(CONTENT_MD5)); assertEquals("autoTagkey", response.getHeader("Encrypted-Data-Key")); //test for specific tag. has higher propority than auto tag. response = new MockHttpServletResponse(); - String specificTagContent = "1234566autotag"; - when(configRocksDbDiskService.getTagContent(dataId, group, tenant, specificTag)).thenReturn(specificTagContent); - actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, specificTag, "true", "localhost"); + when(configRocksDbDiskService.getGrayContent(dataId, group, tenant, + TagGrayRule.TYPE_TAG + "_" + specificTag)).thenReturn(specificTagContent); + actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, specificTag, "true", + "localhost"); assertEquals(HttpServletResponse.SC_OK + "", actualValue); assertEquals(specificTagContent, response.getContentAsString()); - assertEquals("md5specificTag11", response.getHeader(CONTENT_MD5)); + assertEquals(MD5Utils.md5Hex(specificTagContent, "UTF-8"), response.getHeader(CONTENT_MD5)); assertEquals("specificTagkey", response.getHeader("Encrypted-Data-Key")); // test for specific tag ,not exist - when(configRocksDbDiskService.getTagContent(dataId, group, tenant, "auto-tag-test-not-exist")).thenReturn(null); + when(configRocksDbDiskService.getGrayContent(dataId, group, tenant, + TagGrayRule.TYPE_TAG + "_" + "auto-tag-test-not-exist")).thenReturn(null); response = new MockHttpServletResponse(); - actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, "auto-tag-test-not-exist", "true", - "localhost"); + actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, + "auto-tag-test-not-exist", "true", "localhost"); assertEquals(HttpServletResponse.SC_NOT_FOUND + "", actualValue); String expectedContent = "config data not exist"; String actualContent = response.getContentAsString(); @@ -248,25 +277,26 @@ void testDoGetConfigFormal() throws Exception { String dataId = "dataId1234552333"; String group = "group"; String tenant = "tenant"; - configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))) - .thenReturn(1); + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))).thenReturn(1); //mock cache item . CacheItem cacheItem = new CacheItem("test"); - cacheItem.setBeta(false); String md5 = "md5wertyui"; String content = "content345678"; cacheItem.getConfigCache().setMd5Utf8(md5); long ts = System.currentTimeMillis(); cacheItem.getConfigCache().setLastModifiedTs(ts); cacheItem.getConfigCache().setEncryptedDataKey("key2345678"); - configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataId, group, tenant))) + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataId, group, tenant))) .thenReturn(cacheItem); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); when(configRocksDbDiskService.getContent(dataId, group, tenant)).thenReturn(content); - String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, null, "true", "localhost"); + String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, null, "true", + "localhost"); assertEquals(content, response.getContentAsString()); assertEquals(HttpServletResponse.SC_OK + "", actualValue); assertEquals(md5, response.getHeader(CONTENT_MD5)); @@ -279,25 +309,26 @@ void testDoGetConfigFormalV2() throws Exception { String dataId = "dataId1234552333V2"; String group = "group"; String tenant = "tenant"; - configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))) - .thenReturn(1); + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))).thenReturn(1); //mock cache item . CacheItem cacheItem = new CacheItem("test"); - cacheItem.setBeta(false); String md5 = "md5wertyui"; String content = "content345678"; cacheItem.getConfigCache().setMd5Utf8(md5); long ts = System.currentTimeMillis(); cacheItem.getConfigCache().setLastModifiedTs(ts); cacheItem.getConfigCache().setEncryptedDataKey("key2345678"); - configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataId, group, tenant))) + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataId, group, tenant))) .thenReturn(cacheItem); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); when(configRocksDbDiskService.getContent(dataId, group, tenant)).thenReturn(content); - String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, null, "true", "localhost", true); + String actualValue = configServletInner.doGetConfig(request, response, dataId, group, tenant, null, "true", + "localhost", true); assertEquals(JacksonUtils.toJson(Result.success(content)), response.getContentAsString()); assertEquals(HttpServletResponse.SC_OK + "", actualValue); assertEquals(md5, response.getHeader(CONTENT_MD5)); @@ -312,14 +343,17 @@ void testDoGetConfigNotExist() throws Exception { configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(anyString())).thenReturn(0); MockHttpServletRequest request = new MockHttpServletRequest(); MockHttpServletResponse response = new MockHttpServletResponse(); - String actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "test", "true", "localhost"); + String actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "test", "true", + "localhost"); assertEquals(HttpServletResponse.SC_NOT_FOUND + "", actualValue); - configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentCache(GroupKey2.getKey("test", "test", "test"))) + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.getContentCache(GroupKey2.getKey("test", "test", "test"))) .thenReturn(new CacheItem(GroupKey2.getKey("test", "test", "test"))); // if lockResult less than 0 configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(anyString())).thenReturn(-1); - actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "test", "true", "localhost"); + actualValue = configServletInner.doGetConfig(request, response, "test", "test", "test", "test", "true", + "localhost"); assertEquals(HttpServletResponse.SC_CONFLICT + "", actualValue); } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandlerTest.java index 81e7aad105d..0db8cdfb4d0 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandlerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigChangeClusterSyncRequestHandlerTest.java @@ -21,6 +21,7 @@ import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.api.remote.response.ResponseCode; +import com.alibaba.nacos.config.server.service.ConfigGrayModelMigrateService; import com.alibaba.nacos.config.server.service.dump.DumpService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -29,8 +30,13 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import static com.alibaba.nacos.api.ability.constant.AbilityKey.SUPPORT_NEW_GRAY_MODEL; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @ExtendWith(MockitoExtension.class) class ConfigChangeClusterSyncRequestHandlerTest { @@ -40,9 +46,13 @@ class ConfigChangeClusterSyncRequestHandlerTest { @Mock private DumpService dumpService; + @Mock + private ConfigGrayModelMigrateService configGrayModelMigrateService; + @BeforeEach void setUp() throws IOException { - configChangeClusterSyncRequestHandler = new ConfigChangeClusterSyncRequestHandler(dumpService); + configChangeClusterSyncRequestHandler = new ConfigChangeClusterSyncRequestHandler(dumpService, + configGrayModelMigrateService); } @Test @@ -59,4 +69,62 @@ void testHandle() throws NacosException { configChangeSyncRequest, meta); assertEquals(configChangeClusterSyncResponse.getResultCode(), ResponseCode.SUCCESS.getCode()); } + + @Test + void testHandleBetaCompatibleFromNewServer() throws NacosException { + ConfigChangeClusterSyncRequest configChangeSyncRequest = new ConfigChangeClusterSyncRequest(); + configChangeSyncRequest.setRequestId(""); + configChangeSyncRequest.setDataId("dataId"); + configChangeSyncRequest.setGroup("group123"); + configChangeSyncRequest.setTenant("tenant..."); + configChangeSyncRequest.setLastModified(1L); + configChangeSyncRequest.setBeta(true); + RequestMeta meta = new RequestMeta(); + meta.setClientIp("1.1.1.1"); + Map abilityTable = new HashMap<>(); + abilityTable.put(SUPPORT_NEW_GRAY_MODEL.getName(), true); + meta.setAbilityTable(abilityTable); + ConfigChangeClusterSyncResponse configChangeClusterSyncResponse = configChangeClusterSyncRequestHandler.handle( + configChangeSyncRequest, meta); + verify(configGrayModelMigrateService, times(0)).checkMigrateBeta(configChangeSyncRequest.getDataId(), + configChangeSyncRequest.getGroup(), configChangeSyncRequest.getTenant()); + assertEquals(configChangeClusterSyncResponse.getResultCode(), ResponseCode.SUCCESS.getCode()); + } + + @Test + void testHandleBetaCompatibleFromOldServer() throws NacosException { + ConfigChangeClusterSyncRequest configChangeSyncRequest = new ConfigChangeClusterSyncRequest(); + configChangeSyncRequest.setRequestId(""); + configChangeSyncRequest.setDataId("dataId"); + configChangeSyncRequest.setGroup("group123"); + configChangeSyncRequest.setTenant("tenant..."); + configChangeSyncRequest.setLastModified(1L); + configChangeSyncRequest.setBeta(true); + RequestMeta meta = new RequestMeta(); + meta.setClientIp("1.1.1.1"); + ConfigChangeClusterSyncResponse configChangeClusterSyncResponse = configChangeClusterSyncRequestHandler.handle( + configChangeSyncRequest, meta); + verify(configGrayModelMigrateService, times(1)).checkMigrateBeta(configChangeSyncRequest.getDataId(), + configChangeSyncRequest.getGroup(), configChangeSyncRequest.getTenant()); + assertEquals(configChangeClusterSyncResponse.getResultCode(), ResponseCode.SUCCESS.getCode()); + } + + @Test + void testHandleOldCompatibleFromOldServer() throws NacosException { + ConfigChangeClusterSyncRequest configChangeSyncRequest = new ConfigChangeClusterSyncRequest(); + configChangeSyncRequest.setRequestId(""); + configChangeSyncRequest.setDataId("dataId"); + configChangeSyncRequest.setGroup("group123"); + configChangeSyncRequest.setTenant("tenant..."); + configChangeSyncRequest.setTag("tag1234"); + configChangeSyncRequest.setLastModified(1L); + RequestMeta meta = new RequestMeta(); + meta.setClientIp("1.1.1.1"); + ConfigChangeClusterSyncResponse configChangeClusterSyncResponse = configChangeClusterSyncRequestHandler.handle( + configChangeSyncRequest, meta); + verify(configGrayModelMigrateService, times(1)).checkMigrateTag(configChangeSyncRequest.getDataId(), + configChangeSyncRequest.getGroup(), configChangeSyncRequest.getTenant(), + configChangeSyncRequest.getTag()); + assertEquals(configChangeClusterSyncResponse.getResultCode(), ResponseCode.SUCCESS.getCode()); + } } \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandlerTest.java index d5ffb5c0a38..c743239647b 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandlerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigPublishRequestHandlerTest.java @@ -29,8 +29,11 @@ import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.model.event.ConfigDataChangeEvent; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; import com.alibaba.nacos.config.server.service.AggrWhitelist; +import com.alibaba.nacos.config.server.service.ConfigOperationService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.persistence.configuration.DatasourceConfiguration; @@ -52,6 +55,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -67,6 +71,9 @@ class ConfigPublishRequestHandlerTest { @Mock ConfigInfoTagPersistService configInfoTagPersistService; + @Mock + ConfigInfoGrayPersistService configInfoGrayPersistService; + MockedStatic aggrWhitelistMockedStatic; MockedStatic envUtilMockedStatic; @@ -77,9 +84,9 @@ class ConfigPublishRequestHandlerTest { void setUp() { aggrWhitelistMockedStatic = Mockito.mockStatic(AggrWhitelist.class); envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); - - configPublishRequestHandler = new ConfigPublishRequestHandler(configInfoPersistService, configInfoTagPersistService, - configInfoBetaPersistService); + ConfigOperationService configOperationService = new ConfigOperationService(configInfoPersistService, + configInfoTagPersistService, configInfoBetaPersistService, configInfoGrayPersistService); + configPublishRequestHandler = new ConfigPublishRequestHandler(configOperationService); DatasourceConfiguration.setEmbeddedStorage(false); } @@ -203,8 +210,8 @@ public Class subscribeType() { long id = timestamp / 1000; configOperateResult.setId(id); configOperateResult.setLastModified(timestamp); - when(configInfoPersistService.insertOrUpdateCas(eq(requestMeta.getClientIp()), eq(srcUser), any(ConfigInfo.class), - any(Map.class))).thenReturn(configOperateResult); + when(configInfoPersistService.insertOrUpdateCas(eq(requestMeta.getClientIp()), eq(srcUser), + any(ConfigInfo.class), any(Map.class))).thenReturn(configOperateResult); ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta); assertEquals(ResponseCode.SUCCESS.getCode(), response.getResultCode()); @@ -272,8 +279,8 @@ public Class subscribeType() { long id = timestamp / 1000; configOperateResult.setId(id); configOperateResult.setLastModified(timestamp); - when(configInfoPersistService.insertOrUpdateCas(eq(requestMeta.getClientIp()), eq(srcUser), any(ConfigInfo.class), - any(Map.class))).thenThrow(new NacosRuntimeException(502, "mock error")); + when(configInfoPersistService.insertOrUpdateCas(eq(requestMeta.getClientIp()), eq(srcUser), + any(ConfigInfo.class), any(Map.class))).thenThrow(new NacosRuntimeException(502, "mock error")); ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta); assertEquals(ResponseCode.FAIL.getCode(), response.getResultCode()); @@ -370,8 +377,10 @@ public Class subscribeType() { long id = timestamp / 1000; configOperateResult.setId(id); configOperateResult.setLastModified(timestamp); - when(configInfoBetaPersistService.insertOrUpdateBeta(any(ConfigInfo.class), eq(betaIps), eq(requestMeta.getClientIp()), - eq(srcUser))).thenReturn(configOperateResult); + when(configInfoBetaPersistService.insertOrUpdateBeta(any(ConfigInfo.class), eq(betaIps), + eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGray(any(ConfigInfo.class), eq(BetaGrayRule.TYPE_BETA), + anyString(), eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(configOperateResult); ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta); assertEquals(ResponseCode.SUCCESS.getCode(), response.getResultCode()); @@ -381,8 +390,7 @@ public Class subscribeType() { assertEquals(group, reference.get().group); assertEquals(tenant, reference.get().tenant); assertEquals(timestamp, reference.get().lastModifiedTs); - assertFalse(reference.get().isBatch); - assertTrue(reference.get().isBeta); + assertEquals("beta", reference.get().grayName); } @@ -432,8 +440,10 @@ public Class subscribeType() { long id = timestamp / 1000; configOperateResult.setId(id); configOperateResult.setLastModified(timestamp); - when(configInfoBetaPersistService.insertOrUpdateBetaCas(any(ConfigInfo.class), eq(betaIps), eq(requestMeta.getClientIp()), - eq(srcUser))).thenReturn(configOperateResult); + when(configInfoBetaPersistService.insertOrUpdateBetaCas(any(ConfigInfo.class), eq(betaIps), + eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGrayCas(any(ConfigInfo.class), eq(BetaGrayRule.TYPE_BETA), + anyString(), eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(configOperateResult); ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta); assertEquals(ResponseCode.SUCCESS.getCode(), response.getResultCode()); @@ -443,8 +453,8 @@ public Class subscribeType() { assertEquals(group, reference.get().group); assertEquals(tenant, reference.get().tenant); assertEquals(timestamp, reference.get().lastModifiedTs); - assertFalse(reference.get().isBatch); - assertTrue(reference.get().isBeta); + assertEquals(tenant, reference.get().tenant); + assertEquals("beta", reference.get().grayName); } @@ -495,9 +505,10 @@ public Class subscribeType() { long id = timestamp / 1000; configOperateResult.setId(id); configOperateResult.setLastModified(timestamp); - when(configInfoTagPersistService.insertOrUpdateTag(any(ConfigInfo.class), eq(tag), eq(requestMeta.getClientIp()), - eq(srcUser))).thenReturn(configOperateResult); - + when(configInfoTagPersistService.insertOrUpdateTag(any(ConfigInfo.class), eq(tag), + eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGray(any(ConfigInfo.class), eq("tag_" + tag), anyString(), + eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(configOperateResult); ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta); assertEquals(ResponseCode.SUCCESS.getCode(), response.getResultCode()); @@ -507,9 +518,8 @@ public Class subscribeType() { assertEquals(group, reference.get().group); assertEquals(tenant, reference.get().tenant); assertEquals(timestamp, reference.get().lastModifiedTs); - assertFalse(reference.get().isBatch); - assertFalse(reference.get().isBeta); - assertEquals(tag, reference.get().tag); + + assertEquals("tag_" + tag, reference.get().grayName); } @@ -554,9 +564,10 @@ public Class subscribeType() { long id = timestamp / 1000; configOperateResult.setId(id); configOperateResult.setLastModified(timestamp); - when(configInfoTagPersistService.insertOrUpdateTagCas(any(ConfigInfo.class), eq(tag), eq(requestMeta.getClientIp()), - eq(srcUser))).thenReturn(configOperateResult); - + when(configInfoTagPersistService.insertOrUpdateTagCas(any(ConfigInfo.class), eq(tag), + eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGrayCas(any(ConfigInfo.class), eq("tag_" + tag), anyString(), + eq(requestMeta.getClientIp()), eq(srcUser))).thenReturn(configOperateResult); ConfigPublishResponse response = configPublishRequestHandler.handle(configPublishRequest, requestMeta); assertEquals(ResponseCode.SUCCESS.getCode(), response.getResultCode()); @@ -566,10 +577,7 @@ public Class subscribeType() { assertEquals(group, reference.get().group); assertEquals(tenant, reference.get().tenant); assertEquals(timestamp, reference.get().lastModifiedTs); - assertFalse(reference.get().isBatch); - assertFalse(reference.get().isBeta); - assertEquals(tag, reference.get().tag); - + assertEquals("tag_" + tag, reference.get().grayName); } } \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java index 6467ad8e948..7762f6f56c0 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/remote/ConfigQueryRequestHandlerTest.java @@ -21,7 +21,11 @@ import com.alibaba.nacos.api.remote.request.RequestMeta; import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.config.server.model.CacheItem; -import com.alibaba.nacos.config.server.model.ConfigCache; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; +import com.alibaba.nacos.config.server.model.gray.BetaGrayRule; +import com.alibaba.nacos.config.server.model.gray.ConfigGrayPersistInfo; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; +import com.alibaba.nacos.config.server.model.gray.TagGrayRule; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.dump.disk.ConfigRocksDbDiskService; @@ -38,7 +42,6 @@ import org.springframework.core.env.StandardEnvironment; import java.io.IOException; -import java.util.Arrays; import static com.alibaba.nacos.api.common.Constants.VIPSERVER_TAG; import static com.alibaba.nacos.api.config.remote.response.ConfigQueryResponse.CONFIG_NOT_FOUND; @@ -140,14 +143,16 @@ void testGetBeta() throws Exception { when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService); CacheItem cacheItem = new CacheItem(groupKey); - cacheItem.initBetaCacheIfEmpty(); + cacheItem.initConfigGrayIfEmpty(BetaGrayRule.TYPE_BETA); String content = "content_from_beta_notdirectreadÄãºÃ" + System.currentTimeMillis(); - cacheItem.getConfigCacheBeta().setMd5Gbk(MD5Utils.md5Hex(content, "GBK")); - cacheItem.getConfigCacheBeta().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8")); - cacheItem.getConfigCacheBeta().setEncryptedDataKey("key_testGetBeta_NotDirectRead"); - cacheItem.setBeta(true); - cacheItem.setIps4Beta(Arrays.asList("127.0.0.1")); - + ConfigCacheGray configCacheGrayBeta = cacheItem.getConfigCacheGray().get(BetaGrayRule.TYPE_BETA); + configCacheGrayBeta.setMd5Gbk(MD5Utils.md5Hex(content, "GBK")); + configCacheGrayBeta.setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8")); + configCacheGrayBeta.setEncryptedDataKey("key_testGetBeta_NotDirectRead"); + ConfigGrayPersistInfo configGrayPersistInfo = new ConfigGrayPersistInfo(BetaGrayRule.TYPE_BETA, + BetaGrayRule.VERSION, "127.0.0.1", -1000); + configCacheGrayBeta.resetGrayRule(GrayRuleManager.serializeConfigGrayPersistInfo(configGrayPersistInfo)); + cacheItem.sortConfigGray(); when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem); ConfigQueryRequest configQueryRequest = new ConfigQueryRequest(); @@ -156,7 +161,8 @@ void testGetBeta() throws Exception { RequestMeta requestMeta = new RequestMeta(); requestMeta.setClientIp("127.0.0.1"); - when(configRocksDbDiskService.getBetaContent(eq(dataId), eq(group), eq(null))).thenReturn(content); + when(configRocksDbDiskService.getGrayContent(eq(dataId), eq(group), eq(null), + eq(BetaGrayRule.TYPE_BETA))).thenReturn(content); ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta); //check content&md5 assertEquals(content, response.getContent()); @@ -229,16 +235,19 @@ void testGetTagWithTag() throws Exception { cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8")); cacheItem.getConfigCache().setEncryptedDataKey("key_formal"); - ConfigCache configCacheTag = new ConfigCache(); + String specificTag = "specific_tag"; + cacheItem.initConfigGrayIfEmpty(TagGrayRule.TYPE_TAG + "_" + specificTag); + ConfigCacheGray configCacheGrayTag = cacheItem.getConfigCacheGray() + .get(TagGrayRule.TYPE_TAG + "_" + specificTag); String tagContent = "content_from_specific_tag_directreadÄãºÃ" + System.currentTimeMillis(); - configCacheTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK")); - configCacheTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8")); - configCacheTag.setEncryptedDataKey("key_testGetTag_NotDirectRead"); - cacheItem.initConfigTagsIfEmpty(); + configCacheGrayTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK")); + configCacheGrayTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8")); + configCacheGrayTag.setEncryptedDataKey("key_testGetTag_NotDirectRead"); + ConfigGrayPersistInfo configGrayPersistInfo = new ConfigGrayPersistInfo(TagGrayRule.TYPE_TAG, + TagGrayRule.VERSION, specificTag, -999); + configCacheGrayTag.resetGrayRule(GrayRuleManager.serializeConfigGrayPersistInfo(configGrayPersistInfo)); + cacheItem.sortConfigGray(); //specific tag to get - String specificTag = "specific_tag"; - //just for compare. - cacheItem.getConfigCacheTags().put(specificTag, configCacheTag); when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem); ConfigQueryRequest configQueryRequest = new ConfigQueryRequest(); @@ -251,7 +260,8 @@ void testGetTagWithTag() throws Exception { requestMeta.setClientIp("127.0.0.1"); //mock disk read. - when(configRocksDbDiskService.getTagContent(eq(dataId), eq(group), eq(null), eq(specificTag))).thenReturn(tagContent); + when(configRocksDbDiskService.getGrayContent(eq(dataId), eq(group), eq(null), + eq(TagGrayRule.TYPE_TAG + "_" + specificTag))).thenReturn(tagContent); ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta); //check content&md5 @@ -277,28 +287,31 @@ void testGetTagAutoTag() throws Exception { ConfigRocksDbDiskService configRocksDbDiskService = Mockito.mock(ConfigRocksDbDiskService.class); when(ConfigDiskServiceFactory.getInstance()).thenReturn(configRocksDbDiskService); + String autoTag = "auto_tag"; CacheItem cacheItem = new CacheItem(groupKey); + cacheItem.initConfigGrayIfEmpty(TagGrayRule.TYPE_TAG + "_" + autoTag); cacheItem.getConfigCache().setMd5Gbk(MD5Utils.md5Hex(content, "GBK")); cacheItem.getConfigCache().setMd5Utf8(MD5Utils.md5Hex(content, "UTF-8")); - ConfigCache configCacheTag = new ConfigCache(); + ConfigCacheGray configCacheGrayTag = cacheItem.getConfigCacheGray().get(TagGrayRule.TYPE_TAG + "_" + autoTag); String tagContent = "content_from_specific_tag_directreadÄãºÃ" + System.currentTimeMillis(); - configCacheTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK")); - configCacheTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8")); - configCacheTag.setEncryptedDataKey("key_testGetTag_AutoTag_NotDirectRead"); - cacheItem.initConfigTagsIfEmpty(); - String autoTag = "auto_tag"; - cacheItem.getConfigCacheTags().put(autoTag, configCacheTag); + configCacheGrayTag.setMd5Gbk(MD5Utils.md5Hex(tagContent, "GBK")); + configCacheGrayTag.setMd5Utf8(MD5Utils.md5Hex(tagContent, "UTF-8")); + configCacheGrayTag.setEncryptedDataKey("key_testGetTag_AutoTag_NotDirectRead"); + ConfigGrayPersistInfo configGrayPersistInfo = new ConfigGrayPersistInfo(TagGrayRule.TYPE_TAG, + TagGrayRule.VERSION, autoTag, -999); + configCacheGrayTag.resetGrayRule(GrayRuleManager.serializeConfigGrayPersistInfo(configGrayPersistInfo)); + cacheItem.sortConfigGray(); when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(cacheItem); ConfigQueryRequest configQueryRequest = new ConfigQueryRequest(); configQueryRequest.setDataId(dataId); configQueryRequest.setGroup(group); - configQueryRequest.putHeader(VIPSERVER_TAG, autoTag); RequestMeta requestMeta = new RequestMeta(); requestMeta.setClientIp("127.0.0.1"); - + requestMeta.getAppLabels().put(VIPSERVER_TAG, autoTag); //mock disk read. - when(configRocksDbDiskService.getTagContent(eq(dataId), eq(group), eq(null), eq(autoTag))).thenReturn(tagContent); + when(configRocksDbDiskService.getGrayContent(eq(dataId), eq(group), eq(null), + eq(TagGrayRule.TYPE_TAG + "_" + autoTag))).thenReturn(tagContent); ConfigQueryResponse response = configQueryRequestHandler.handle(configQueryRequest, requestMeta); //check content&md5 @@ -324,8 +337,8 @@ void testGetConfigNotExistAndConflict() throws Exception { String group = "group" + System.currentTimeMillis(); String tenant = "tenant" + System.currentTimeMillis(); //test config not exist - configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))) - .thenReturn(0); + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))).thenReturn(0); final String groupKey = GroupKey2.getKey(dataId, group, tenant); when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(null); @@ -345,8 +358,8 @@ void testGetConfigNotExistAndConflict() throws Exception { //test config conflict when(ConfigCacheService.getContentCache(eq(groupKey))).thenReturn(new CacheItem(groupKey)); - configCacheServiceMockedStatic.when(() -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))) - .thenReturn(-1); + configCacheServiceMockedStatic.when( + () -> ConfigCacheService.tryConfigReadLock(GroupKey2.getKey(dataId, group, tenant))).thenReturn(-1); ConfigQueryResponse responseConflict = configQueryRequestHandler.handle(configQueryRequest, requestMeta); assertEquals(ConfigQueryResponse.CONFIG_QUERY_CONFLICT, responseConflict.getErrorCode()); assertNull(responseConflict.getContent()); diff --git a/config/src/test/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifierTest.java b/config/src/test/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifierTest.java index 98e0806b46f..a838db8d737 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifierTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/remote/RpcConfigChangeNotifierTest.java @@ -131,7 +131,7 @@ void testOnDataEvent() throws InterruptedException { //mock push tps passed Mockito.when(tpsControlManager.check(any(TpsCheckRequest.class))).thenReturn(new TpsCheckResponse(true, 200, "success")); - rpcConfigChangeNotifier.onEvent(new LocalDataChangeEvent(groupKey, true, betaIps)); + rpcConfigChangeNotifier.onEvent(new LocalDataChangeEvent(groupKey)); //wait rpc push executed. Thread.sleep(50L); //expect rpc push task run. diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigCacheServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigCacheServiceTest.java index fccdb2e5b90..b23610b1e1b 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigCacheServiceTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigCacheServiceTest.java @@ -18,7 +18,8 @@ import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.config.server.model.CacheItem; -import com.alibaba.nacos.config.server.model.ConfigCache; +import com.alibaba.nacos.config.server.model.ConfigCacheGray; +import com.alibaba.nacos.config.server.model.gray.GrayRuleManager; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.utils.GroupKey2; @@ -37,8 +38,6 @@ import java.io.IOException; import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -67,7 +66,8 @@ class ConfigCacheServiceTest { void before() { envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); configDiskServiceFactoryMockedStatic = Mockito.mockStatic(ConfigDiskServiceFactory.class); - configDiskServiceFactoryMockedStatic.when(() -> ConfigDiskServiceFactory.getInstance()).thenReturn(configDiskService); + configDiskServiceFactoryMockedStatic.when(() -> ConfigDiskServiceFactory.getInstance()) + .thenReturn(configDiskService); propertyUtilMockedStatic = Mockito.mockStatic(PropertyUtil.class); } @@ -92,7 +92,8 @@ void testDumpFormal() throws Exception { long ts = System.currentTimeMillis(); String type = "json"; String encryptedDataKey = "key12345"; - boolean result = ConfigCacheService.dumpWithMd5(dataId, group, tenant, content, md5, ts, type, encryptedDataKey); + boolean result = ConfigCacheService.dumpWithMd5(dataId, group, tenant, content, md5, ts, type, + encryptedDataKey); assertTrue(result); //verify cache. CacheItem contentCache1 = ConfigCacheService.getContentCache(groupKey); @@ -132,7 +133,8 @@ void testDumpFormal() throws Exception { .saveToDisk(anyString(), anyString(), anyString(), anyString()); try { long newTs3 = newTs2 + 123L; - boolean dumpErrorResult = ConfigCacheService.dump(dataId, group, tenant, contentNew + "234567", newTs3, type, encryptedDataKey); + boolean dumpErrorResult = ConfigCacheService.dump(dataId, group, tenant, contentNew + "234567", newTs3, + type, encryptedDataKey); envUtilMockedStatic.verify(() -> EnvUtil.systemExit(), times(1)); assertFalse(dumpErrorResult); } catch (Throwable throwable) { @@ -149,163 +151,100 @@ void testDumpFormal() throws Exception { } @Test - void testDumpBeta() throws Exception { + public void testDumpGray() throws Exception { String dataId = "dataIdtestDumpBetaNewCache123"; String group = "group11"; String tenant = "tenant112"; - String content = "mockContnet11"; + String grayName = "grayName"; + String grayRule = "{\"type\":\"tag\",\"version\":\"1.0.0\",\"expr\":\"dgray123\",\"priority\":1}"; + String content = "mockContent11"; + String md5 = MD5Utils.md5Hex(content, "UTF-8"); String groupKey = GroupKey2.getKey(dataId, group, tenant); String encryptedDataKey = "key12345"; - List betaIps = Arrays.asList("127.0.0.1", "127.0.0.2"); long ts = System.currentTimeMillis(); - //init beta cache - boolean result = ConfigCacheService.dumpBeta(dataId, group, tenant, content, ts, String.join(",", betaIps), encryptedDataKey); + //init gray cache + boolean result = ConfigCacheService.dumpGray(dataId, group, tenant, grayName, grayRule, content, ts, + encryptedDataKey); assertTrue(result); CacheItem contentCache = ConfigCacheService.getContentCache(groupKey); - assertEquals(md5, contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(ts, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertEquals(betaIps, contentCache.getIps4Beta()); - assertEquals(encryptedDataKey, contentCache.getConfigCacheBeta().getEncryptedDataKey()); - Mockito.verify(configDiskService, times(1)).saveBetaToDisk(eq(dataId), eq(group), eq(tenant), eq(content)); + assertEquals(md5, contentCache.getConfigCacheGray().get(grayName).getMd5Utf8()); + assertEquals(ts, contentCache.getConfigCacheGray().get(grayName).getLastModifiedTs()); + assertEquals(encryptedDataKey, contentCache.getConfigCacheGray().get(grayName).getEncryptedDataKey()); + Mockito.verify(configDiskService, times(1)) + .saveGrayToDisk(eq(dataId), eq(group), eq(tenant), eq(grayName), eq(content)); //ts newer ,md5 update long tsNew = System.currentTimeMillis(); String contentNew = content + tsNew; String md5New = MD5Utils.md5Hex(contentNew, "UTF-8"); - List betaIpsNew = Arrays.asList("127.0.0.1", "127.0.0.2", "127.0.0.3"); - boolean resultNew = ConfigCacheService.dumpBeta(dataId, group, tenant, contentNew, tsNew, String.join(",", betaIpsNew), + boolean resultNew = ConfigCacheService.dumpGray(dataId, group, tenant, grayName, grayRule, contentNew, tsNew, encryptedDataKey); assertTrue(resultNew); - assertEquals(md5New, contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(tsNew, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertEquals(encryptedDataKey, contentCache.getConfigCacheBeta().getEncryptedDataKey()); - assertEquals(betaIpsNew, contentCache.getIps4Beta()); - Mockito.verify(configDiskService, times(1)).saveBetaToDisk(eq(dataId), eq(group), eq(tenant), eq(contentNew)); + assertEquals(md5New, contentCache.getConfigCacheGray().get(grayName).getMd5Utf8()); + assertEquals(tsNew, contentCache.getConfigCacheGray().get(grayName).getLastModifiedTs()); + assertEquals(encryptedDataKey, contentCache.getConfigCacheGray().get(grayName).getEncryptedDataKey()); + Mockito.verify(configDiskService, times(1)) + .saveGrayToDisk(eq(dataId), eq(group), eq(tenant), eq(grayName), eq(contentNew)); //ts old ,md5 update long tsOld = tsNew - 1; String contentWithOldTs = "contentWithOldTs" + tsOld; - List betaIpsWithOldTs = Arrays.asList("127.0.0.1", "127.0.0.2", "127.0.0.4"); - boolean resultOld = ConfigCacheService.dumpBeta(dataId, group, tenant, contentWithOldTs, tsOld, String.join(",", betaIpsWithOldTs), - encryptedDataKey); + boolean resultOld = ConfigCacheService.dumpGray(dataId, group, tenant, grayName, grayRule, contentWithOldTs, + tsOld, encryptedDataKey); assertTrue(resultOld); - assertEquals(md5New, contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(tsNew, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertEquals(encryptedDataKey, contentCache.getConfigCacheBeta().getEncryptedDataKey()); - assertEquals(betaIpsNew, contentCache.getIps4Beta()); - Mockito.verify(configDiskService, times(0)).saveBetaToDisk(eq(dataId), eq(group), eq(tenant), eq(contentWithOldTs)); + assertEquals(md5New, contentCache.getConfigCacheGray().get(grayName).getMd5Utf8()); + assertEquals(tsNew, contentCache.getConfigCacheGray().get(grayName).getLastModifiedTs()); + assertEquals(encryptedDataKey, contentCache.getConfigCacheGray().get(grayName).getEncryptedDataKey()); + Mockito.verify(configDiskService, times(0)) + .saveGrayToDisk(eq(dataId), eq(group), eq(tenant), eq(grayName), eq(contentWithOldTs)); - //ts new ,md5 not update,beta ips list changes + //ts new ,md5 not update,grayRule changes long tsNew2 = tsNew + 1; + String grayRuleNew = "{\"type\":\"tag\",\"version\":\"1.0.0\",\"expr\":\"gray1234\",\"priority\":1}"; + String contentWithPrev = contentNew; - List betaIpsNew2 = Arrays.asList("127.0.0.1", "127.0.0.2", "127.0.0.4", "127.0.0.5"); - boolean resultNew2 = ConfigCacheService.dumpBeta(dataId, group, tenant, contentWithPrev, tsNew2, String.join(",", betaIpsNew2), - encryptedDataKey); + boolean resultNew2 = ConfigCacheService.dumpGray(dataId, group, tenant, grayName, grayRuleNew, contentWithPrev, + tsNew2, encryptedDataKey); assertTrue(resultNew2); - assertEquals(md5New, contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(tsNew2, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertEquals(encryptedDataKey, contentCache.getConfigCacheBeta().getEncryptedDataKey()); - assertEquals(betaIpsNew2, contentCache.getIps4Beta()); + assertEquals(md5New, contentCache.getConfigCacheGray().get(grayName).getMd5Utf8()); + assertEquals(tsNew2, contentCache.getConfigCacheGray().get(grayName).getLastModifiedTs()); + assertEquals(encryptedDataKey, contentCache.getConfigCacheGray().get(grayName).getEncryptedDataKey()); + assertEquals(GrayRuleManager.constructGrayRule(GrayRuleManager.deserializeConfigGrayPersistInfo(grayRuleNew)), + contentCache.getConfigCacheGray().get(grayName).getGrayRule()); //ts new only,md5 not update,beta ips not change long tsNew3 = tsNew2 + 1; String contentWithPrev2 = contentNew; - List betaIpsNew3 = betaIpsNew2; - boolean resultNew3 = ConfigCacheService.dumpBeta(dataId, group, tenant, contentWithPrev2, tsNew3, String.join(",", betaIpsNew3), - encryptedDataKey); + String grayRulePrev = grayRuleNew; + boolean resultNew3 = ConfigCacheService.dumpGray(dataId, group, tenant, grayName, grayRulePrev, + contentWithPrev2, tsNew3, encryptedDataKey); assertTrue(resultNew3); - assertEquals(md5New, contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(tsNew3, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertEquals(encryptedDataKey, contentCache.getConfigCacheBeta().getEncryptedDataKey()); - assertEquals(betaIpsNew2, contentCache.getIps4Beta()); + assertEquals(md5New, contentCache.getConfigCacheGray().get(grayName).getMd5Utf8()); + assertEquals(tsNew3, contentCache.getConfigCacheGray().get(grayName).getLastModifiedTs()); + assertEquals(encryptedDataKey, contentCache.getConfigCacheGray().get(grayName).getEncryptedDataKey()); + assertEquals(GrayRuleManager.constructGrayRule(GrayRuleManager.deserializeConfigGrayPersistInfo(grayRuleNew)), + contentCache.getConfigCacheGray().get(grayName).getGrayRule()); //ts not update,md5 not update,beta ips not change long tsNew4 = tsNew3; String contentWithPrev4 = contentNew; - List betaIpsNew4 = betaIpsNew2; - boolean resultNew4 = ConfigCacheService.dumpBeta(dataId, group, tenant, contentWithPrev4, tsNew4, String.join(",", betaIpsNew4), - encryptedDataKey); + boolean resultNew4 = ConfigCacheService.dumpGray(dataId, group, tenant, grayName, grayRulePrev, + contentWithPrev4, tsNew4, encryptedDataKey); assertTrue(resultNew4); - assertEquals(md5New, contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(tsNew3, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertEquals(encryptedDataKey, contentCache.getConfigCacheBeta().getEncryptedDataKey()); - assertEquals(betaIpsNew4, contentCache.getIps4Beta()); + assertEquals(md5New, contentCache.getConfigCacheGray().get(grayName).getMd5Utf8()); + assertEquals(tsNew3, contentCache.getConfigCacheGray().get(grayName).getLastModifiedTs()); + assertEquals(encryptedDataKey, contentCache.getConfigCacheGray().get(grayName).getEncryptedDataKey()); + assertEquals(GrayRuleManager.constructGrayRule(GrayRuleManager.deserializeConfigGrayPersistInfo(grayRuleNew)), + contentCache.getConfigCacheGray().get(grayName).getGrayRule()); //test remove - boolean removeBeta = ConfigCacheService.removeBeta(dataId, group, tenant); + boolean removeBeta = ConfigCacheService.removeGray(dataId, group, tenant, grayName); assertTrue(removeBeta); - Mockito.verify(configDiskService, times(1)).removeConfigInfo4Beta(dataId, group, tenant); - ConfigCache betaCacheAfterRemove = ConfigCacheService.getContentCache(groupKey).getConfigCacheBeta(); - assertNull(betaCacheAfterRemove); - } - - @Test - void testDumpTag() throws Exception { - String dataId = "dataIdtestDumpTag133323"; - String group = "group11"; - String tenant = "tenant112"; - String content = "mockContnet11"; - String tag = "tag12345"; - String groupKey = GroupKey2.getKey(dataId, group, tenant); - String encryptedDataKey = "key12345"; - long ts = System.currentTimeMillis(); - - //init dump tag - boolean dumpTagResult = ConfigCacheService.dumpTag(dataId, group, tenant, tag, content, ts, encryptedDataKey); - assertTrue(dumpTagResult); - Mockito.verify(configDiskService, times(1)).saveTagToDisk(eq(dataId), eq(group), eq(tenant), eq(tag), eq(content)); - CacheItem contentCache = ConfigCacheService.getContentCache(groupKey); - ConfigCache configCacheTag = contentCache.getConfigCacheTags().get(tag); - assertEquals(ts, configCacheTag.getLastModifiedTs()); - String md5 = MD5Utils.md5Hex(content, "UTF-8"); - assertEquals(md5, configCacheTag.getMd5Utf8()); - - //ts newer ,md5 update - long tsNew = System.currentTimeMillis(); - String contentNew = content + tsNew; - String md5New = MD5Utils.md5Hex(contentNew, "UTF-8"); - boolean resultNew = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentNew, tsNew, encryptedDataKey); - assertTrue(resultNew); - assertEquals(md5New, configCacheTag.getMd5Utf8()); - assertEquals(tsNew, configCacheTag.getLastModifiedTs()); - assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey()); - Mockito.verify(configDiskService, times(1)).saveTagToDisk(eq(dataId), eq(group), eq(tenant), eq(tag), eq(contentNew)); - - //ts old ,md5 update - long tsOld = tsNew - 1; - String contentWithOldTs = "contentWithOldTs" + tsOld; - boolean resultOld = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentWithOldTs, tsOld, encryptedDataKey); - assertTrue(resultOld); - assertEquals(md5New, configCacheTag.getMd5Utf8()); - assertEquals(tsNew, configCacheTag.getLastModifiedTs()); - assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey()); - Mockito.verify(configDiskService, times(0)).saveTagToDisk(eq(dataId), eq(group), eq(tenant), eq(tag), eq(contentWithOldTs)); - - //ts new only,md5 not update - long tsNew2 = tsNew + 1; - String contentWithPrev2 = contentNew; - boolean resultNew2 = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentWithPrev2, tsNew2, encryptedDataKey); - assertTrue(resultNew2); - assertEquals(md5New, configCacheTag.getMd5Utf8()); - assertEquals(tsNew2, configCacheTag.getLastModifiedTs()); - assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey()); - - //ts not update,md5 not update - long tsNew3 = tsNew2; - String contentWithPrev3 = contentNew; - boolean resultNew3 = ConfigCacheService.dumpTag(dataId, group, tenant, tag, contentWithPrev3, tsNew3, encryptedDataKey); - assertTrue(resultNew3); - assertEquals(md5New, configCacheTag.getMd5Utf8()); - assertEquals(tsNew3, configCacheTag.getLastModifiedTs()); - assertEquals(encryptedDataKey, configCacheTag.getEncryptedDataKey()); - - //test remove - boolean removeTag = ConfigCacheService.removeTag(dataId, group, tenant, tag); - assertTrue(removeTag); - Mockito.verify(configDiskService, times(1)).removeConfigInfo4Tag(dataId, group, tenant, tag); - Map configCacheTags = ConfigCacheService.getContentCache(groupKey).getConfigCacheTags(); - assertNull(configCacheTags); + Mockito.verify(configDiskService, times(1)).removeConfigInfo4Gray(dataId, group, tenant, grayName); + Map grayCacheAfterRemove = ConfigCacheService.getContentCache(groupKey) + .getConfigCacheGray(); + assertNull(grayCacheAfterRemove); } @Test diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigOperationServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigOperationServiceTest.java index 7451b7214dc..48414cd2098 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigOperationServiceTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/ConfigOperationServiceTest.java @@ -22,6 +22,7 @@ import com.alibaba.nacos.config.server.model.ConfigRequestInfo; import com.alibaba.nacos.config.server.model.form.ConfigForm; import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.sys.env.EnvUtil; @@ -34,6 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -59,15 +61,18 @@ class ConfigOperationServiceTest { @Mock private ConfigInfoBetaPersistService configInfoBetaPersistService; + @Mock + private ConfigInfoGrayPersistService configInfoGrayPersistService; + @BeforeEach void setUp() throws Exception { EnvUtil.setEnvironment(new StandardEnvironment()); this.configOperationService = new ConfigOperationService(configInfoPersistService, configInfoTagPersistService, - configInfoBetaPersistService); + configInfoBetaPersistService, configInfoGrayPersistService); } @Test - void testPublishConfig() throws NacosException { + void testPublishConfigBeta() throws NacosException { ConfigForm configForm = new ConfigForm(); configForm.setDataId("test"); configForm.setGroup("test"); @@ -75,55 +80,115 @@ void testPublishConfig() throws NacosException { ConfigRequestInfo configRequestInfo = new ConfigRequestInfo(); - // if betaIps is blank, tag is blank and casMd5 is blank - when(configInfoPersistService.insertOrUpdate(any(), any(), any(ConfigInfo.class), any())).thenReturn(new ConfigOperateResult()); - Boolean aResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); - verify(configInfoPersistService).insertOrUpdate(any(), any(), any(ConfigInfo.class), any()); - assertTrue(aResult); + configRequestInfo.setCasMd5(""); + configForm.setTag(""); - // if betaIps is blank, tag is blank and casMd5 is not blank + // if betaIps is not blank and casMd5 is blank + configRequestInfo.setBetaIps("test-betaIps"); + when(configInfoBetaPersistService.insertOrUpdateBeta(any(ConfigInfo.class), eq("test-betaIps"), any(), + any())).thenReturn(new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGray(any(ConfigInfo.class), eq("beta"), anyString(), + eq(configRequestInfo.getSrcIp()), eq(configForm.getSrcUser()))).thenReturn(new ConfigOperateResult()); + Boolean eResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); + verify(configInfoBetaPersistService).insertOrUpdateBeta(any(ConfigInfo.class), eq("test-betaIps"), any(), + any()); + assertTrue(eResult); + + } + + @Test + void testPublishConfigBetaCas() throws NacosException { + ConfigForm configForm = new ConfigForm(); + configForm.setDataId("test"); + configForm.setGroup("test"); + configForm.setContent("test content"); + + ConfigRequestInfo configRequestInfo = new ConfigRequestInfo(); + + configRequestInfo.setCasMd5("casMd5"); + configForm.setTag(""); + + // if betaIps is not blank and casMd5 is not blank + configRequestInfo.setBetaIps("test-betaIps"); configRequestInfo.setCasMd5("test casMd5"); - when(configInfoPersistService.insertOrUpdateCas(any(), any(), any(ConfigInfo.class), any())).thenReturn(new ConfigOperateResult()); - Boolean bResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); - verify(configInfoPersistService).insertOrUpdateCas(any(), any(), any(ConfigInfo.class), any()); - assertTrue(bResult); + when(configInfoBetaPersistService.insertOrUpdateBetaCas(any(ConfigInfo.class), eq("test-betaIps"), any(), + any())).thenReturn(new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGrayCas(any(ConfigInfo.class), eq("beta"), anyString(), + eq(configRequestInfo.getSrcIp()), eq(configForm.getSrcUser()))).thenReturn(new ConfigOperateResult()); + Boolean fResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); + verify(configInfoBetaPersistService).insertOrUpdateBetaCas(any(ConfigInfo.class), eq("test-betaIps"), any(), + any()); + assertTrue(fResult); + } + + @Test + void testPublishConfigTag() throws NacosException { + ConfigForm configForm = new ConfigForm(); + configForm.setDataId("test"); + configForm.setGroup("test"); + configForm.setContent("test content"); + + ConfigRequestInfo configRequestInfo = new ConfigRequestInfo(); + configRequestInfo.setCasMd5(""); + String tag = "testTag"; + configForm.setTag(tag); - // if betaIps is blank, tag is not blank and casMd5 is blank - configForm.setTag("test tag"); - when(configInfoTagPersistService.insertOrUpdateTag(any(ConfigInfo.class), eq("test tag"), any(), any())).thenReturn( + when(configInfoTagPersistService.insertOrUpdateTag(any(ConfigInfo.class), eq(tag), any(), any())).thenReturn( new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGray(any(ConfigInfo.class), eq("tag_" + tag), anyString(), + eq(configRequestInfo.getSrcIp()), eq(configForm.getSrcUser()))).thenReturn(new ConfigOperateResult()); Boolean cResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); - verify(configInfoTagPersistService).insertOrUpdateTag(any(ConfigInfo.class), eq("test tag"), any(), any()); + verify(configInfoTagPersistService).insertOrUpdateTag(any(ConfigInfo.class), eq(tag), any(), any()); assertTrue(cResult); - // if betaIps is blank, tag is not blank and casMd5 is not blank - configForm.setTag("test tag"); - configRequestInfo.setCasMd5("test casMd5"); - when(configInfoTagPersistService.insertOrUpdateTagCas(any(ConfigInfo.class), eq("test tag"), any(), any())).thenReturn( + } + + @Test + void testPublishConfigTagCas() throws NacosException { + ConfigForm configForm = new ConfigForm(); + configForm.setDataId("test"); + configForm.setGroup("test"); + configForm.setContent("test content"); + + ConfigRequestInfo configRequestInfo = new ConfigRequestInfo(); + + configRequestInfo.setCasMd5("casMd5"); + String tag = "testTag"; + configForm.setTag(tag); + when(configInfoTagPersistService.insertOrUpdateTagCas(any(ConfigInfo.class), eq(tag), any(), any())).thenReturn( new ConfigOperateResult()); + when(configInfoGrayPersistService.insertOrUpdateGrayCas(any(ConfigInfo.class), eq("tag_" + tag), anyString(), + eq(configRequestInfo.getSrcIp()), eq(configForm.getSrcUser()))).thenReturn(new ConfigOperateResult()); Boolean dResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); - verify(configInfoTagPersistService).insertOrUpdateTagCas(any(ConfigInfo.class), eq("test tag"), any(), any()); + verify(configInfoTagPersistService).insertOrUpdateTagCas(any(ConfigInfo.class), eq(tag), any(), any()); assertTrue(dResult); - configRequestInfo.setCasMd5(""); - configForm.setTag(""); + } + + @Test + void testPublishConfig() throws NacosException { + ConfigForm configForm = new ConfigForm(); + configForm.setDataId("test"); + configForm.setGroup("test"); + configForm.setContent("test content"); - // if betaIps is not blank and casMd5 is blank - configRequestInfo.setBetaIps("test-betaIps"); - when(configInfoBetaPersistService.insertOrUpdateBeta(any(ConfigInfo.class), eq("test-betaIps"), any(), any())).thenReturn( + ConfigRequestInfo configRequestInfo = new ConfigRequestInfo(); + + // if betaIps is blank, tag is blank and casMd5 is blank + when(configInfoPersistService.insertOrUpdate(any(), any(), any(ConfigInfo.class), any())).thenReturn( new ConfigOperateResult()); - Boolean eResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); - verify(configInfoBetaPersistService).insertOrUpdateBeta(any(ConfigInfo.class), eq("test-betaIps"), any(), any()); - assertTrue(eResult); + Boolean aResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); + verify(configInfoPersistService).insertOrUpdate(any(), any(), any(ConfigInfo.class), any()); + assertTrue(aResult); - // if betaIps is not blank and casMd5 is not blank - configRequestInfo.setBetaIps("test-betaIps"); + // if betaIps is blank, tag is blank and casMd5 is not blank configRequestInfo.setCasMd5("test casMd5"); - when(configInfoBetaPersistService.insertOrUpdateBetaCas(any(ConfigInfo.class), eq("test-betaIps"), any(), any())).thenReturn( + when(configInfoPersistService.insertOrUpdateCas(any(), any(), any(ConfigInfo.class), any())).thenReturn( new ConfigOperateResult()); - Boolean fResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); - verify(configInfoBetaPersistService).insertOrUpdateBetaCas(any(ConfigInfo.class), eq("test-betaIps"), any(), any()); - assertTrue(fResult); + Boolean bResult = configOperationService.publishConfig(configForm, configRequestInfo, ""); + verify(configInfoPersistService).insertOrUpdateCas(any(), any(), any(ConfigInfo.class), any()); + assertTrue(bResult); + configRequestInfo.setCasMd5(""); } @Test @@ -136,7 +201,8 @@ void testDeleteConfig() { // if tag is not blank Boolean bResult = configOperationService.deleteConfig("test", "test", "", "test", "1.1.1.1", "test"); - verify(configInfoTagPersistService).removeConfigInfoTag(eq("test"), eq("test"), eq(""), eq("test"), any(), any()); + verify(configInfoTagPersistService).removeConfigInfoTag(eq("test"), eq("test"), eq(""), eq("test"), any(), + any()); assertTrue(bResult); } } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java index cde308bce33..77f2944d07d 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java @@ -105,8 +105,7 @@ void after() throws IllegalAccessException { dynamicDataSourceMockedStatic.close(); envUtilMockedStatic.close(); ConfigDiskServiceFactory.getInstance().clearAll(); - ConfigDiskServiceFactory.getInstance().clearAllBeta(); - ConfigDiskServiceFactory.getInstance().clearAllTag(); + ConfigDiskServiceFactory.getInstance().clearAllGray(); Field[] declaredFields = ConfigDiskServiceFactory.class.getDeclaredFields(); for (Field filed : declaredFields) { diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java new file mode 100644 index 00000000000..ac8d0d7f9bb --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.dump; + +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.service.ConfigCacheService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExecutor; +import com.alibaba.nacos.config.server.utils.GroupKey; +import com.alibaba.nacos.config.server.utils.PropertyUtil; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class DumpChangeGrayConfigWorkerTest { + + DumpChangeGrayConfigWorker dumpGrayConfigWorker; + + @Mock + ConfigInfoGrayPersistService configInfoGrayPersistService; + + static MockedStatic envUtilMockedStatic; + + static MockedStatic configCacheServiceMockedStatic; + + static MockedStatic configExecutorMockedStatic; + + + /** + * Clean up. + */ + @AfterEach + public void after() { + envUtilMockedStatic.close(); + configCacheServiceMockedStatic.close(); + configExecutorMockedStatic.close(); + + } + + @BeforeEach + public void setUp() { + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + configCacheServiceMockedStatic = Mockito.mockStatic(ConfigCacheService.class); + configExecutorMockedStatic = Mockito.mockStatic(ConfigExecutor.class); + + envUtilMockedStatic.when(() -> EnvUtil.getAvailableProcessors(anyInt())).thenReturn(2); + dumpGrayConfigWorker = new DumpChangeGrayConfigWorker(configInfoGrayPersistService, + new Timestamp(System.currentTimeMillis())); + } + + @Test + public void testdumpGrayConfigWorkerRun() { + List mockList = new ArrayList<>(); + ConfigInfoGrayWrapper mock1 = mock(1); + mockList.add(mock1); + when(configInfoGrayPersistService.findChangeConfig(any(Timestamp.class), any(long.class), eq(100))).thenReturn( + mockList); + configCacheServiceMockedStatic.when(() -> ConfigCacheService.getContentMd5( + eq(GroupKey.getKeyTenant(mock1.getDataId(), mock1.getGroup(), mock1.getTenant())))).thenReturn(""); + + dumpGrayConfigWorker.run(); + //verify dump gray executed + configCacheServiceMockedStatic.verify( + () -> ConfigCacheService.dumpGray(eq(mock1.getDataId()), eq(mock1.getGroup()), eq(mock1.getTenant()), + eq(mock1.getGrayName()), eq(mock1.getGrayRule()), eq(mock1.getContent()), + eq(mock1.getLastModified()), eq(mock1.getEncryptedDataKey()))); + //verify task scheduled + configExecutorMockedStatic.verify(() -> ConfigExecutor.scheduleConfigChangeTask(any(DumpChangeGrayConfigWorker.class), + eq(PropertyUtil.getDumpChangeWorkerInterval()), eq(TimeUnit.MILLISECONDS))); + + } + + ConfigInfoGrayWrapper mock(int id) { + ConfigInfoGrayWrapper configInfoGrayWrapper = new ConfigInfoGrayWrapper(); + configInfoGrayWrapper.setDataId("mockdataid" + id); + configInfoGrayWrapper.setGroup("mockgroup" + id); + configInfoGrayWrapper.setTenant("tenant" + id); + configInfoGrayWrapper.setContent("content" + id); + configInfoGrayWrapper.setGrayName("graytags1" + id); + configInfoGrayWrapper.setGrayRule( + "{\"type\":\"tagv2\",\"version\":\"1.0.0\",\"expr\":\"middleware.server.key\\u003dgray123\",\"priority\":1}"); + return configInfoGrayWrapper; + } +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java index d01fc330d12..ad869bbae7c 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorTest.java @@ -18,8 +18,6 @@ import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.config.server.model.CacheItem; -import com.alibaba.nacos.config.server.model.ConfigInfoBetaWrapper; -import com.alibaba.nacos.config.server.model.ConfigInfoTagWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoWrapper; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskService; @@ -27,9 +25,8 @@ import com.alibaba.nacos.config.server.service.dump.disk.ConfigRocksDbDiskService; import com.alibaba.nacos.config.server.service.dump.processor.DumpProcessor; import com.alibaba.nacos.config.server.service.dump.task.DumpTask; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; @@ -46,7 +43,6 @@ import java.io.IOException; import java.lang.reflect.Field; -import java.util.Arrays; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -67,10 +63,7 @@ class DumpProcessorTest { ConfigInfoPersistService configInfoPersistService; @Mock - ConfigInfoBetaPersistService configInfoBetaPersistService; - - @Mock - ConfigInfoTagPersistService configInfoTagPersistService; + ConfigInfoGrayPersistService configInfoGrayPersistService; ExternalDumpService dumpService; @@ -90,9 +83,9 @@ void init() throws Exception { when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); - dumpService = new ExternalDumpService(configInfoPersistService, null, null, null, configInfoBetaPersistService, - configInfoTagPersistService, null, null); - dumpProcessor = new DumpProcessor(configInfoPersistService, configInfoBetaPersistService, configInfoTagPersistService); + dumpService = new ExternalDumpService(configInfoPersistService, null, null, null, + configInfoGrayPersistService, null, null); + dumpProcessor = new DumpProcessor(configInfoPersistService, configInfoGrayPersistService); Field[] declaredFields = ConfigDiskServiceFactory.class.getDeclaredFields(); for (Field filed : declaredFields) { if (filed.getName().equals("configDiskService")) { @@ -112,8 +105,7 @@ void after() { dynamicDataSourceMockedStatic.close(); envUtilMockedStatic.close(); ConfigDiskServiceFactory.getInstance().clearAll(); - ConfigDiskServiceFactory.getInstance().clearAllBeta(); - ConfigDiskServiceFactory.getInstance().clearAllTag(); + ConfigDiskServiceFactory.getInstance().clearAllGray(); } @@ -135,7 +127,7 @@ void testDumpNormalAndRemove() throws IOException { String handlerIp = "127.0.0.1"; long lastModified = System.currentTimeMillis(); - DumpTask dumpTask = new DumpTask(GroupKey2.getKey(dataId, group, tenant), false, false, false, null, lastModified, handlerIp); + DumpTask dumpTask = new DumpTask(GroupKey2.getKey(dataId, group, tenant), null, lastModified, handlerIp); boolean process = dumpProcessor.process(dumpTask); assertTrue(process); @@ -161,98 +153,4 @@ void testDumpNormalAndRemove() throws IOException { assertNull(contentFromDiskAfterRemove); } - - @Test - void testDumpBetaAndRemove() throws IOException { - String dataId = "testDataIdBeta"; - String group = "testGroup"; - String tenant = "testTenant"; - String content = "testContentBeta你好" + System.currentTimeMillis(); - long time = System.currentTimeMillis(); - ConfigInfoBetaWrapper configInfoWrapper = new ConfigInfoBetaWrapper(); - configInfoWrapper.setDataId(dataId); - configInfoWrapper.setGroup(group); - configInfoWrapper.setTenant(tenant); - configInfoWrapper.setContent(content); - configInfoWrapper.setLastModified(time); - String betaIps = "127.0.0.1123,127.0.0.11"; - configInfoWrapper.setBetaIps(betaIps); - - Mockito.when(configInfoBetaPersistService.findConfigInfo4Beta(eq(dataId), eq(group), eq(tenant))).thenReturn(configInfoWrapper); - - String handlerIp = "127.0.0.1"; - long lastModified = System.currentTimeMillis(); - DumpTask dumpTask = new DumpTask(GroupKey2.getKey(dataId, group, tenant), true, false, false, null, lastModified, handlerIp); - boolean process = dumpProcessor.process(dumpTask); - assertTrue(process); - - //Check cache - CacheItem contentCache = ConfigCacheService.getContentCache(GroupKey2.getKey(dataId, group, tenant)); - assertEquals(MD5Utils.md5Hex(content, "UTF-8"), contentCache.getConfigCacheBeta().getMd5Utf8()); - assertEquals(time, contentCache.getConfigCacheBeta().getLastModifiedTs()); - assertTrue(contentCache.ips4Beta.containsAll(Arrays.asList(betaIps.split(",")))); - //check disk - String contentFromDisk = ConfigDiskServiceFactory.getInstance().getBetaContent(dataId, group, tenant); - assertEquals(content, contentFromDisk); - - // remove - Mockito.when(configInfoBetaPersistService.findConfigInfo4Beta(eq(dataId), eq(group), eq(tenant))).thenReturn(null); - boolean processRemove = dumpProcessor.process(dumpTask); - assertTrue(processRemove); - - //Check cache - CacheItem contentCacheAfterRemove = ConfigCacheService.getContentCache(GroupKey2.getKey(dataId, group, tenant)); - assertTrue(contentCacheAfterRemove == null || contentCacheAfterRemove.getConfigCacheBeta() == null); - //check disk - String contentFromDiskAfterRemove = ConfigDiskServiceFactory.getInstance().getBetaContent(dataId, group, tenant); - assertNull(contentFromDiskAfterRemove); - - } - - @Test - void testDumpTagAndRemove() throws IOException { - String dataId = "testDataIdBeta"; - String group = "testGroup"; - String tenant = "testTenant"; - String tag = "testTag111"; - String content = "testContentBeta你好" + System.currentTimeMillis(); - long time = System.currentTimeMillis(); - ConfigInfoTagWrapper configInfoWrapper = new ConfigInfoTagWrapper(); - configInfoWrapper.setDataId(dataId); - configInfoWrapper.setGroup(group); - configInfoWrapper.setTenant(tenant); - configInfoWrapper.setContent(content); - configInfoWrapper.setLastModified(time); - configInfoWrapper.setTag(tag); - Mockito.when(configInfoTagPersistService.findConfigInfo4Tag(eq(dataId), eq(group), eq(tenant), eq(tag))) - .thenReturn(configInfoWrapper); - - String handlerIp = "127.0.0.1"; - long lastModified = System.currentTimeMillis(); - DumpTask dumpTask = new DumpTask(GroupKey2.getKey(dataId, group, tenant), false, false, true, tag, lastModified, handlerIp); - boolean process = dumpProcessor.process(dumpTask); - assertTrue(process); - - //Check cache - CacheItem contentCache = ConfigCacheService.getContentCache(GroupKey2.getKey(dataId, group, tenant)); - assertEquals(MD5Utils.md5Hex(content, "UTF-8"), contentCache.getConfigCacheTags().get(tag).getMd5Utf8()); - assertEquals(time, contentCache.getConfigCacheTags().get(tag).getLastModifiedTs()); - //check disk - String contentFromDisk = ConfigDiskServiceFactory.getInstance().getTagContent(dataId, group, tenant, tag); - assertEquals(content, contentFromDisk); - - // remove - Mockito.when(configInfoTagPersistService.findConfigInfo4Tag(eq(dataId), eq(group), eq(tenant), eq(tag))).thenReturn(null); - boolean processRemove = dumpProcessor.process(dumpTask); - assertTrue(processRemove); - - //Check cache - CacheItem contentCacheAfterRemove = ConfigCacheService.getContentCache(GroupKey2.getKey(dataId, group, tenant)); - assertTrue(contentCacheAfterRemove == null || contentCache.getConfigCacheTags() == null - || contentCache.getConfigCacheTags().get(tag) == null); - //check disk - String contentFromDiskAfterRemove = ConfigDiskServiceFactory.getInstance().getTagContent(dataId, group, tenant, tag); - assertNull(contentFromDiskAfterRemove); - - } } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorUserRwaDiskTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorUserRwaDiskTest.java index 27a3bf09fc9..41f464686ce 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorUserRwaDiskTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpProcessorUserRwaDiskTest.java @@ -49,14 +49,4 @@ public void testDumpNormalAndRemove() throws IOException { super.testDumpNormalAndRemove(); } - - @Test - public void testDumpBetaAndRemove() throws IOException { - super.testDumpBetaAndRemove(); - } - - @Test - public void testDumpTagAndRemove() throws IOException { - super.testDumpTagAndRemove(); - } } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java index 884561422d1..6b32eca2913 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpServiceTest.java @@ -22,9 +22,8 @@ import com.alibaba.nacos.config.server.service.dump.task.DumpTask; import com.alibaba.nacos.config.server.service.merge.MergeDatumService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoAggrPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.GroupKey; @@ -81,10 +80,7 @@ class DumpServiceTest { ConfigInfoAggrPersistService configInfoAggrPersistService; @Mock - ConfigInfoBetaPersistService configInfoBetaPersistService; - - @Mock - ConfigInfoTagPersistService configInfoTagPersistService; + ConfigInfoGrayPersistService configInfoGrayPersistService; @Mock MergeDatumService mergeDatumService; @@ -118,7 +114,7 @@ void setUp() { ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "localDataSourceService", dataSourceService); ReflectionTestUtils.setField(DynamicDataSource.getInstance(), "basicDataSourceService", dataSourceService); dumpService = new ExternalDumpService(configInfoPersistService, namespacePersistService, historyConfigInfoPersistService, - configInfoAggrPersistService, configInfoBetaPersistService, configInfoTagPersistService, mergeDatumService, memberManager); + configInfoAggrPersistService, configInfoGrayPersistService, mergeDatumService, memberManager); configExecutorMocked = Mockito.mockStatic(ConfigExecutor.class); historyConfigCleanerManagerMockedStatic = Mockito.mockStatic(HistoryConfigCleanerManager.class); historyConfigCleanerManagerMockedStatic.when(() -> HistoryConfigCleanerManager.getHistoryConfigCleaner(anyString())) @@ -145,20 +141,11 @@ void dumpRequest() throws Throwable { dumpService.dump(dumpRequest); Mockito.verify(dumpTaskMgr, times(1)) .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant())), any(DumpTask.class)); - dumpRequest.setBeta(true); + + dumpRequest.setGrayName("tag_123"); dumpService.dump(dumpRequest); Mockito.verify(dumpTaskMgr, times(1)) - .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+beta"), any(DumpTask.class)); - dumpRequest.setBeta(false); - dumpRequest.setBatch(true); - dumpService.dump(dumpRequest); - Mockito.verify(dumpTaskMgr, times(1)) - .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+batch"), any(DumpTask.class)); - dumpRequest.setBatch(false); - dumpRequest.setTag("testTag111"); - dumpService.dump(dumpRequest); - Mockito.verify(dumpTaskMgr, times(1)) - .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+tag+" + dumpRequest.getTag()), + .addTask(eq(GroupKey.getKeyTenant(dataId, group, dumpRequest.getTenant()) + "+gray+" + dumpRequest.getGrayName()), any(DumpTask.class)); } @@ -194,8 +181,7 @@ void dumpOperate() throws Throwable { // expect dump Mockito.verify(configInfoPersistService, times(1)).findAllConfigInfoFragment(0, 100, true); Mockito.verify(configInfoPersistService, times(1)).findConfigMaxId(); - Mockito.verify(configInfoBetaPersistService, times(1)).configInfoBetaCount(); - Mockito.verify(configInfoTagPersistService, times(1)).configInfoTagCount(); + Mockito.verify(configInfoGrayPersistService, times(1)).configInfoGrayCount(); Mockito.verify(mergeDatumService, times(2)).executeConfigsMerge(anyList()); @@ -204,11 +190,9 @@ void dumpOperate() throws Throwable { configExecutorMocked.verify( () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllProcessorRunner.class), anyLong(), anyLong(), eq(TimeUnit.MINUTES)), times(1)); + configExecutorMocked.verify( - () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllBetaProcessorRunner.class), anyLong(), anyLong(), - eq(TimeUnit.MINUTES)), times(1)); - configExecutorMocked.verify( - () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllTagProcessorRunner.class), anyLong(), anyLong(), + () -> ConfigExecutor.scheduleConfigTask(any(DumpService.DumpAllGrayProcessorRunner.class), anyLong(), anyLong(), eq(TimeUnit.MINUTES)), times(1)); configExecutorMocked.verify( () -> ConfigExecutor.scheduleConfigChangeTask(any(DumpChangeConfigWorker.class), anyLong(), eq(TimeUnit.MILLISECONDS)), diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskServiceTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskServiceTest.java index a0cce0f95f6..b7e1e182788 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskServiceTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/disk/ConfigRawDiskServiceTest.java @@ -45,7 +45,8 @@ private boolean isWindows() { */ @Test void testTargetFile() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - Method method = ConfigRawDiskService.class.getDeclaredMethod("targetFile", String.class, String.class, String.class); + Method method = ConfigRawDiskService.class.getDeclaredMethod("targetFile", String.class, String.class, + String.class); method.setAccessible(true); File result = (File) method.invoke(null, "aaaa?dsaknkf", "aaaa*dsaknkf", "aaaa:dsaknkf"); // 分解路径 @@ -65,50 +66,27 @@ void testTargetFile() throws NoSuchMethodException, IllegalAccessException, Invo * 测试获取beta文件路径. */ @Test - void testTargetBetaFile() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - Method method = ConfigRawDiskService.class.getDeclaredMethod("targetBetaFile", String.class, String.class, String.class); + void testTargetGrayFile() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Method method = ConfigRawDiskService.class.getDeclaredMethod("targetGrayFile", String.class, String.class, + String.class, String.class); method.setAccessible(true); - File result = (File) method.invoke(null, "aaaa?dsaknkf", "aaaa*dsaknkf", "aaaa:dsaknkf"); + File result = (File) method.invoke(null, "data345678", "group3456", "tenant1234", "graynem4567"); // 分解路径 Path path = Paths.get(result.getPath()); Path parent = path.getParent(); Path grandParent = parent.getParent(); + Path grand2Parent = grandParent.getParent(); + // 获取最后三段路径 - String lastSegment = path.getFileName().toString(); - String secondLastSegment = parent.getFileName().toString(); + String fourthLastSegment = grand2Parent.getFileName().toString(); + assertEquals(fourthLastSegment, "tenant1234"); String thirdLastSegment = grandParent.getFileName().toString(); - assertEquals(isWindows() ? "aaaa%A3%dsaknkf" : thirdLastSegment, thirdLastSegment); - assertEquals(isWindows() ? "aaaa%A4%dsaknkf" : secondLastSegment, secondLastSegment); - assertEquals(isWindows() ? "aaaa%A5%dsaknkf" : lastSegment, lastSegment); - - } - - /** - * 测试获取tag文件路径. - * - * @throws NoSuchMethodException 方法不存在异常 - * @throws IllegalAccessException 非法访问异常 - * @throws InvocationTargetException 目标异常 - */ - @Test - void testTargetTagFile() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - Method method = ConfigRawDiskService.class.getDeclaredMethod("targetTagFile", String.class, String.class, String.class, - String.class); - method.setAccessible(true); - File result = (File) method.invoke(null, "aaaa?dsaknkf", "aaaa*dsaknkf", "aaaa:dsaknkf", "aaaadsaknkf"); - // 分解路径 - Path path = Paths.get(result.getPath()); - Path parent = path.getParent(); - Path grandParent = parent.getParent(); - Path greatGrandParent = grandParent.getParent(); - // 获取最后四段路径 + assertEquals(isWindows() ? "aaaa%A3%dsaknkf" : thirdLastSegment, "group3456"); String secondLastSegment = parent.getFileName().toString(); - String thirdLastSegment = grandParent.getFileName().toString(); - String fourthLastSegment = greatGrandParent.getFileName().toString(); - assertEquals(isWindows() ? "aaaa%A3%dsaknkf" : fourthLastSegment, fourthLastSegment); - assertEquals(isWindows() ? "aaaa%A4%dsaknkf" : thirdLastSegment, thirdLastSegment); - assertEquals(isWindows() ? "aaaa%A5%dsaknkf" : secondLastSegment, secondLastSegment); + assertEquals(isWindows() ? "aaaa%A4%dsaknkf" : secondLastSegment, "data345678"); String lastSegment = path.getFileName().toString(); - assertEquals("aaaadsaknkf", lastSegment); + assertEquals(isWindows() ? "aaaa%A5%dsaknkf" : lastSegment, "graynem4567"); + } + } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java index 206d950adcf..b03ea592ba7 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/processor/DumpAllProcessorTest.java @@ -23,9 +23,8 @@ import com.alibaba.nacos.config.server.service.dump.ExternalDumpService; import com.alibaba.nacos.config.server.service.dump.disk.ConfigDiskServiceFactory; import com.alibaba.nacos.config.server.service.dump.task.DumpAllTask; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoBetaPersistService; +import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; -import com.alibaba.nacos.config.server.service.repository.ConfigInfoTagPersistService; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.PropertyUtil; import com.alibaba.nacos.persistence.datasource.DataSourceService; @@ -63,10 +62,7 @@ class DumpAllProcessorTest { DataSourceService dataSourceService; @Mock - ConfigInfoBetaPersistService configInfoBetaPersistService; - - @Mock - ConfigInfoTagPersistService configInfoTagPersistService; + ConfigInfoGrayPersistService configInfoGrayPersistService; DumpAllProcessor dumpAllProcessor; @@ -92,8 +88,7 @@ void init() throws Exception { when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); - dumpService = new ExternalDumpService(configInfoPersistService, null, null, null, configInfoBetaPersistService, - configInfoTagPersistService, null, null); + dumpService = new ExternalDumpService(configInfoPersistService, null, null, null, configInfoGrayPersistService, null, null); dumpAllProcessor = new DumpAllProcessor(configInfoPersistService); envUtilMockedStatic.when(() -> EnvUtil.getProperty(eq("memory_limit_file_path"), eq("/sys/fs/cgroup/memory/memory.limit_in_bytes"))) diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java new file mode 100644 index 00000000000..3877461c48e --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java @@ -0,0 +1,363 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.repository.embedded; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +/** + * test for embedded config tag. + * + * @author shiyiyue + */ +@ExtendWith(SpringExtension.class) +public class EmbeddedConfigInfoGrayPersistServiceImplTest { + + private EmbeddedConfigInfoGrayPersistServiceImpl embeddedConfigInfoGrayPersistService; + + @Mock + private DataSourceService dataSourceService; + + MockedStatic envUtilMockedStatic; + + MockedStatic embeddedStorageContextHolderMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + @Mock + DatabaseOperate databaseOperate; + + /** + * before test. + */ + @BeforeEach + public void before() { + embeddedStorageContextHolderMockedStatic = Mockito.mockStatic(EmbeddedStorageContextHolder.class); + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getDataSourceType()).thenReturn("derby"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + embeddedConfigInfoGrayPersistService = new EmbeddedConfigInfoGrayPersistServiceImpl(databaseOperate); + } + + /** + * after each case. + */ + @AfterEach + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + embeddedStorageContextHolderMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateGrayOfAdd() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //mock query config state empty and return obj after insert + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String grayName = "tag123grayName"; + String grayRule = "tag123grayrule"; + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(configInfoStateWrapper); + + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = embeddedConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, + grayName, grayRule, srcIp, srcUser); + + //mock insert invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(grayName), eq(grayRule), eq(appName), eq(content), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class)), times(1)); + assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateGrayOfUpdate() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + //mock query config state and return obj after update + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String grayName = "tag123grayName"; + String grayRule = "tag123grayrule"; + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = embeddedConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, + grayName, grayRule, srcIp, srcUser); + //verify update to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(content), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq(appName), eq(grayRule), eq(dataId), eq(group), eq(tenant), + eq(grayName)), times(1)); + assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateGrayCasOfAdd() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state empty and return obj after insert + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String grayName = "tag123grayName"; + String grayRule = "tag123grayrule"; + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(configInfoStateWrapper); + + String srcIp = "ip345678"; + String srcUser = "user1234567"; + ConfigOperateResult configOperateResult = embeddedConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, + grayName, grayRule, srcIp, srcUser); + //verify insert to be invoked + //mock insert invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(grayName), eq(grayRule), eq(appName), eq(content), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), + any(Timestamp.class), any(Timestamp.class)), times(1)); + assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + + } + + @Test + public void testInsertOrUpdateGrayCasOfUpdate() { + String dataId = "dataId111222"; + String group = "group"; + String tenant = "tenant"; + String appName = "appname1234"; + String content = "c12345"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key23456"); + configInfo.setMd5("casMd5"); + //mock query config state and return obj after update + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setLastModified(System.currentTimeMillis()); + configInfoStateWrapper.setId(234567890L); + String grayName = "tag123grayName"; + String grayRule = "tag123grayrule"; + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) + .thenReturn(configInfoStateWrapper); + String srcIp = "ip345678"; + String srcUser = "user1234567"; + + //mock cas update return 1 + Mockito.when(databaseOperate.blockUpdate()).thenReturn(true); + ConfigOperateResult configOperateResult = embeddedConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, + grayName, grayRule, srcIp, srcUser); + //verify update to be invoked + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(content), + eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), eq(appName), + eq(grayRule), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(configInfo.getMd5())), + times(1)); + assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + } + + @Test + public void testRemoveConfigInfograyName() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + String grayName = "gray123345"; + String srcIp = "ip345678"; + String srcUser = "user1234567"; + embeddedConfigInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, grayName, srcIp, srcUser); + //verify delete sql invoked. + embeddedStorageContextHolderMockedStatic.verify( + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + eq(grayName)), times(1)); + } + + @Test + public void testFindConfigInfo4Gray() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + String grayName = "tag123345"; + + //mock query tag return obj + ConfigInfoGrayWrapper configInfoGrayWrapperMocked = new ConfigInfoGrayWrapper(); + configInfoGrayWrapperMocked.setLastModified(System.currentTimeMillis()); + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenReturn(configInfoGrayWrapperMocked); + + ConfigInfoGrayWrapper configInfo4GrayReturn = embeddedConfigInfoGrayPersistService.findConfigInfo4Gray(dataId, + group, tenant, grayName); + assertEquals(configInfoGrayWrapperMocked, configInfo4GrayReturn); + } + + @Test + public void testConfigInfoGrayCount() { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(308); + //execute & verify + int count = embeddedConfigInfoGrayPersistService.configInfoGrayCount(); + assertEquals(308, count); + } + + @Test + public void testFindAllConfigInfoGrayForDumpAll() { + + //mock count + Mockito.when(databaseOperate.queryOne(anyString(), eq(Integer.class))).thenReturn(308); + List mockGrayList = new ArrayList<>(); + mockGrayList.add(new ConfigInfoGrayWrapper()); + mockGrayList.add(new ConfigInfoGrayWrapper()); + mockGrayList.add(new ConfigInfoGrayWrapper()); + mockGrayList.get(0).setLastModified(System.currentTimeMillis()); + mockGrayList.get(1).setLastModified(System.currentTimeMillis()); + mockGrayList.get(2).setLastModified(System.currentTimeMillis()); + //mock query list + Mockito.when( + databaseOperate.queryMany(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))) + .thenReturn(mockGrayList); + int pageNo = 3; + int pageSize = 100; + //execute & verify + Page returnGrayPage = embeddedConfigInfoGrayPersistService.findAllConfigInfoGrayForDumpAll( + pageNo, pageSize); + assertEquals(308, returnGrayPage.getTotalCount()); + assertEquals(mockGrayList, returnGrayPage.getPageItems()); + } + + @Test + public void testFindConfigInfoGrays() { + String dataId = "dataId1112222"; + String group = "group22"; + String tenant = "tenant2"; + List mockedGrays = Arrays.asList("tags1", "tags11", "tags111"); + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {dataId, group, tenant}), eq(String.class))) + .thenReturn(mockedGrays); + List configInfoGrays = embeddedConfigInfoGrayPersistService.findConfigInfoGrays(dataId, group, tenant); + assertEquals(mockedGrays, configInfoGrays); + } + + @Test + public void testFindChangeConfigInfo4Gray() { + List mockList = new ArrayList<>(); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.get(0).setLastModified(System.currentTimeMillis()); + mockList.get(1).setLastModified(System.currentTimeMillis()); + mockList.get(2).setLastModified(System.currentTimeMillis()); + long lastMaxId = 123; + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + when(databaseOperate.queryMany(anyString(), eq(new Object[] {timestamp, lastMaxId, 100}), + eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenReturn(mockList) + .thenThrow(new CannotGetJdbcConnectionException("mock exception22")); + + List changeConfig = embeddedConfigInfoGrayPersistService.findChangeConfig(timestamp, + lastMaxId, 100); + assertTrue(changeConfig.get(0).getLastModified() == mockList.get(0).getLastModified()); + assertTrue(changeConfig.get(1).getLastModified() == mockList.get(1).getLastModified()); + assertTrue(changeConfig.get(2).getLastModified() == mockList.get(2).getLastModified()); + try { + embeddedConfigInfoGrayPersistService.findChangeConfig(timestamp, lastMaxId, 100); + assertTrue(false); + } catch (CannotGetJdbcConnectionException exception) { + assertEquals("mock exception22", exception.getMessage()); + } + + } + +} diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java new file mode 100644 index 00000000000..4bd2224e28c --- /dev/null +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java @@ -0,0 +1,551 @@ +/* + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.service.repository.extrnal; + +import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.model.ConfigInfo; +import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; +import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.TestCaseUtils; +import com.alibaba.nacos.persistence.datasource.DataSourceService; +import com.alibaba.nacos.persistence.datasource.DynamicDataSource; +import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.sys.env.EnvUtil; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.CannotGetJdbcConnectionException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.transaction.support.TransactionTemplate; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import static com.alibaba.nacos.config.server.constant.Constants.ENCODE; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + +@ExtendWith(SpringExtension.class) +public class ExternalConfigInfoGrayPersistServiceImplTest { + + private ExternalConfigInfoGrayPersistServiceImpl externalConfigInfoGrayPersistService; + + @Mock + private DataSourceService dataSourceService; + + @Mock + private JdbcTemplate jdbcTemplate; + + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); + + MockedStatic envUtilMockedStatic; + + MockedStatic externalStorageUtilsMockedStatic; + + MockedStatic dynamicDataSourceMockedStatic; + + @Mock + DynamicDataSource dynamicDataSource; + + /** + * before each tet case. + */ + @BeforeEach + public void before() { + dynamicDataSourceMockedStatic = Mockito.mockStatic(DynamicDataSource.class); + envUtilMockedStatic = Mockito.mockStatic(EnvUtil.class); + externalStorageUtilsMockedStatic = Mockito.mockStatic(ExternalStorageUtils.class); + when(DynamicDataSource.getInstance()).thenReturn(dynamicDataSource); + when(dynamicDataSource.getDataSource()).thenReturn(dataSourceService); + when(dataSourceService.getTransactionTemplate()).thenReturn(transactionTemplate); + when(dataSourceService.getJdbcTemplate()).thenReturn(jdbcTemplate); + when(dataSourceService.getDataSourceType()).thenReturn("mysql"); + envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) + .thenReturn(false); + externalConfigInfoGrayPersistService = new ExternalConfigInfoGrayPersistServiceImpl(); + } + + /** + * after each test case. + */ + @AfterEach + public void after() { + dynamicDataSourceMockedStatic.close(); + envUtilMockedStatic.close(); + externalStorageUtilsMockedStatic.close(); + } + + @Test + public void testInsertOrUpdateGrayOfUpdate() { + String dataId = "grayDataId113"; + String group = "group"; + String tenant = "tenant"; + //mock exist gray + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + String grayName = "grayName..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper, + mockedConfigInfoStateWrapper); + //execute + + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + String grayRule = "grayRule..."; + ConfigOperateResult configOperateResult = externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, + grayName, grayRule, srcIp, srcUser); + //expect return obj + assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify update to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), + eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), + eq(dataId), eq(group), eq(tenant), eq(grayName)); + + } + + @Test + public void testInsertOrUpdateGrayOfAdd() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + String grayName = "grayName..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)) + .thenReturn(mockedConfigInfoStateWrapper); + + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + String grayRule = "grayRule..."; + + //execute + ConfigOperateResult configOperateResult = externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, + grayName, grayRule, srcIp, srcUser); + //expect return obj + assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify add to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), + eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), + eq(configInfo.getMd5()), eq(srcIp), eq(srcUser)); + } + + @Test + public void testInsertOrUpdateGrayOfException() { + String dataId = "grapDataId113"; + String group = "group113"; + String tenant = "tenant113"; + + //mock exist gray + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + String grayName = "grayName..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("casMd5"); + String grayRule = "grayRule..."; + // mock update throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), + eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), + eq(dataId), eq(group), eq(tenant), eq(grayName))).thenThrow( + new CannotGetJdbcConnectionException("mock fail")); + //execute of update& expect. + try { + externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, grayName, grayRule, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("mock fail", exception.getMessage()); + } + + //mock query return null + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null); + //mock add throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), + eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), + eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser))).thenThrow( + new CannotGetJdbcConnectionException("mock fail add")); + + //execute of add& expect. + try { + externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, grayName, grayRule, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("mock fail add", exception.getMessage()); + } + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("get c fail")); + //execute of add& expect. + try { + externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, grayName, grayRule, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("get c fail", exception.getMessage()); + } + + } + + @Test + public void testInsertOrUpdateGrayCasOfUpdate() { + String dataId = "grayDataId113"; + String group = "group"; + String tenant = "tenant"; + + //mock exist gray + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + String grayName = "grayName..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper, + mockedConfigInfoStateWrapper); + + //execute + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("casMd5"); + String grayRule = "grayRule..."; + //mock cas update + when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), eq(MD5Utils.md5Hex(content, ENCODE)), + eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), eq(dataId), eq(group), eq(tenant), + eq(grayName), eq(configInfo.getMd5()))).thenReturn(1); + + ConfigOperateResult configOperateResult = externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, + grayName, grayRule, srcIp, srcUser); + //expect return obj + assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify cas update to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(configInfo.getContent()), eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), + eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), eq(dataId), eq(group), eq(tenant), + eq(grayName), eq(configInfo.getMd5())); + + } + + @Test + public void testInsertOrUpdateGrayCasOfAdd() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + String grayName = "grayName..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)) + .thenReturn(mockedConfigInfoStateWrapper); + + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("csMd5"); + String grayRule = "grayRule..."; + //execute + ConfigOperateResult configOperateResult = externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, + grayName, grayRule, srcIp, srcUser); + //expect return obj + assertEquals(mockedConfigInfoStateWrapper.getId(), configOperateResult.getId()); + assertEquals(mockedConfigInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); + //verify add to be invoked + Mockito.verify(jdbcTemplate, times(1)) + .update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), + eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), + eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser)); + + } + + @Test + public void testInsertOrUpdateGrayCasOfException() { + String dataId = "betaDataId113"; + String group = "group113"; + String tenant = "tenant113"; + + //mock exist beta + ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + String grayName = "grayName..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String appName = "appname"; + String content = "content111"; + ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); + configInfo.setEncryptedDataKey("key34567"); + configInfo.setMd5("casMd5"); + String grayRule = "grayRule..."; + // mock update throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), eq(MD5Utils.md5Hex(content, ENCODE)), + eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), eq(dataId), eq(group), eq(tenant), + eq(grayName), eq(configInfo.getMd5()))).thenThrow( + new CannotGetJdbcConnectionException("updat mock fail")); + + //execute of update& expect. + try { + externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, grayName, grayRule, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("updat mock fail", exception.getMessage()); + } + + //mock query return null + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null); + //mock add throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), + eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), + eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser))).thenThrow( + new CannotGetJdbcConnectionException("mock fail add")); + + //execute of add& expect. + try { + externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, grayName, grayRule, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("mock fail add", exception.getMessage()); + } + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("get c fail")); + //execute of add& expect. + try { + externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, grayName, grayRule, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("get c fail", exception.getMessage()); + } + + } + + @Test + public void testRemoveConfigInfo4Gray() { + String dataId = "dataId456789"; + String group = "group4567"; + String tenant = "tenant56789o0"; + + String srcIp = "srcUp..."; + String srcUser = "srcUser..."; + String grayName = "grayName1"; + externalConfigInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, grayName, srcIp, srcUser); + + //verity + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName)); + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName))).thenThrow( + new CannotGetJdbcConnectionException("mock fail11111")); + + try { + externalConfigInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, grayName, srcIp, srcUser); + assertTrue(false); + } catch (Exception exception) { + assertEquals("mock fail11111", exception.getMessage()); + } + } + + @Test + public void testFindChangeConfigInfo4Gray() { + List mockList = new ArrayList<>(); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.get(0).setLastModified(System.currentTimeMillis()); + mockList.get(1).setLastModified(System.currentTimeMillis()); + mockList.get(2).setLastModified(System.currentTimeMillis()); + + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + long lastMaxId = 123; + when(jdbcTemplate.query(anyString(), eq(new Object[] {timestamp, lastMaxId, 100}), + eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenReturn(mockList) + .thenThrow(new CannotGetJdbcConnectionException("mock exception22")); + + List changeConfig = externalConfigInfoGrayPersistService.findChangeConfig(timestamp, + lastMaxId, 100); + assertTrue(changeConfig.get(0).getLastModified() == mockList.get(0).getLastModified()); + assertTrue(changeConfig.get(1).getLastModified() == mockList.get(1).getLastModified()); + assertTrue(changeConfig.get(2).getLastModified() == mockList.get(2).getLastModified()); + try { + externalConfigInfoGrayPersistService.findChangeConfig(timestamp, lastMaxId, 100); + assertTrue(false); + } catch (CannotGetJdbcConnectionException exception) { + assertEquals("mock exception22", exception.getMessage()); + } + + } + + @Test + public void testFindConfigInfo4Gray() { + String dataId = "dataId456789"; + String group = "group4567"; + String tenant = "tenant56789o0"; + String grayName = "gray12"; + //mock exist gray + ConfigInfoGrayWrapper mockedConfigInfoStateWrapper = new ConfigInfoGrayWrapper(); + mockedConfigInfoStateWrapper.setDataId(dataId); + mockedConfigInfoStateWrapper.setGroup(group); + mockedConfigInfoStateWrapper.setGrayName(grayName); + mockedConfigInfoStateWrapper.setTenant(tenant); + mockedConfigInfoStateWrapper.setId(123456L); + mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + ConfigInfoGrayWrapper configInfo4GrayReturn = externalConfigInfoGrayPersistService.findConfigInfo4Gray(dataId, + group, tenant, grayName); + assertEquals(mockedConfigInfoStateWrapper, configInfo4GrayReturn); + + //mock query throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenThrow( + new CannotGetJdbcConnectionException("mock fail11111")); + try { + externalConfigInfoGrayPersistService.findConfigInfo4Gray(dataId, group, tenant, grayName); + assertTrue(false); + } catch (Exception exception) { + assertEquals("mock fail11111", exception.getMessage()); + } + + //mock query throw EmptyResultDataAccessException + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenThrow(new EmptyResultDataAccessException(1)); + ConfigInfoGrayWrapper configInfo4GrayNull = externalConfigInfoGrayPersistService.findConfigInfo4Gray(dataId, + group, tenant, grayName); + assertNull(configInfo4GrayNull); + } + + @Test + public void testConfigInfoGrayCount() { + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(101); + int returnCount = externalConfigInfoGrayPersistService.configInfoGrayCount(); + assertEquals(101, returnCount); + } + + @Test + public void testFindAllConfigInfoGrayForDumpAll() { + //mock count + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(12345); + + //mock page list + List mockList = new ArrayList<>(); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.add(new ConfigInfoGrayWrapper()); + mockList.get(0).setLastModified(System.currentTimeMillis()); + mockList.get(1).setLastModified(System.currentTimeMillis()); + mockList.get(2).setLastModified(System.currentTimeMillis()); + + when(jdbcTemplate.query(anyString(), eq(new Object[] {}), eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenReturn( + mockList); + + int pageNo = 1; + int pageSize = 101; + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenReturn(101); + //execute & expect + Page pageReturn = externalConfigInfoGrayPersistService.findAllConfigInfoGrayForDumpAll( + pageNo, pageSize); + assertEquals(mockList, pageReturn.getPageItems()); + assertEquals(101, pageReturn.getTotalCount()); + + //mock count throw CannotGetJdbcConnectionException + when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class))).thenThrow( + new CannotGetJdbcConnectionException("345678909fail")); + //execute &expect + try { + externalConfigInfoGrayPersistService.findAllConfigInfoGrayForDumpAll(pageNo, pageSize); + assertTrue(false); + } catch (Exception exception) { + assertEquals("345678909fail", exception.getMessage()); + } + } + +} + diff --git a/console/src/main/resources/META-INF/derby-schema.sql b/console/src/main/resources/META-INF/derby-schema.sql index be595491b89..69aa36f981f 100644 --- a/console/src/main/resources/META-INF/derby-schema.sql +++ b/console/src/main/resources/META-INF/derby-schema.sql @@ -96,6 +96,26 @@ CREATE TABLE config_info_tag ( constraint configinfotag_id_key PRIMARY KEY (id), constraint uk_configinfotag_datagrouptenanttag UNIQUE (data_id,group_id,tenant_id,tag_id)); +CREATE TABLE config_info_gray ( + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + gray_name varchar(128) NOT NULL, + gray_rule CLOB, + app_name varchar(128), + src_ip varchar(128), + src_user varchar(128) default '', + content CLOB, + md5 varchar(32) DEFAULT NULL, + encrypted_data_key varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + constraint configinfogray_id_key PRIMARY KEY (id), + constraint uk_configinfogray_datagrouptenantgrayname UNIQUE (data_id,group_id,tenant_id,gray_name)); +CREATE INDEX config_info_gray_dataid_gmt_modified ON config_info_gray(data_id,gmt_modified); +CREATE INDEX config_info_gray_gmt_modified ON config_info_gray(gmt_modified); + CREATE TABLE config_info_aggr ( id bigint NOT NULL generated by default as identity, data_id varchar(255) NOT NULL, diff --git a/console/src/main/resources/application.properties b/console/src/main/resources/application.properties index a3629d9118e..a7a41c3d415 100644 --- a/console/src/main/resources/application.properties +++ b/console/src/main/resources/application.properties @@ -33,14 +33,14 @@ server.port=8848 ### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced. # spring.datasource.platform=mysql # nacos.plugin.datasource.log.enabled=true -#spring.sql.init.platform=mysql +spring.sql.init.platform=derby ### Count of DB: -# db.num=1 +db.num=1 ### Connect URL of DB: -# db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC -# db.user=nacos -# db.password=nacos +db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC +db.user=root +db.password=11021102 ### the maximum retry times for push nacos.config.push.maxRetryTime=50 @@ -113,7 +113,7 @@ nacos.security.ignore.urls=/,/error,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/ nacos.core.auth.system.type=nacos ### If turn on auth system: -nacos.core.auth.enabled=false +nacos.core.auth.enabled=true ### Turn on/off caching of auth information. By turning on this switch, the update of auth information would have a 15 seconds delay. nacos.core.auth.caching.enabled=true @@ -123,8 +123,8 @@ nacos.core.auth.enable.userAgentAuthWhite=false ### Since 1.4.1, worked when nacos.core.auth.enabled=true and nacos.core.auth.enable.userAgentAuthWhite=false. ### The two properties is the white list for auth and used by identity the request from other server. -nacos.core.auth.server.identity.key= -nacos.core.auth.server.identity.value= +nacos.core.auth.server.identity.key=servr123 +nacos.core.auth.server.identity.value=servr123value ### worked when nacos.core.auth.system.type=nacos ### The token expiration in seconds: @@ -132,7 +132,7 @@ nacos.core.auth.plugin.nacos.token.cache.enable=false nacos.core.auth.plugin.nacos.token.expire.seconds=18000 ### The default token (Base64 string): #nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 -nacos.core.auth.plugin.nacos.token.secret.key= +nacos.core.auth.plugin.nacos.token.secret.key=key12345key12345key12345SecretKey012345678901234567890123456789012345678901234567890123456789 ### worked when nacos.core.auth.system.type=ldap,{0} is Placeholder,replace login username #nacos.core.auth.ldap.url=ldap://localhost:389 diff --git a/distribution/conf/derby-schema.sql b/distribution/conf/derby-schema.sql index f4e93a3aab6..c27eadf9134 100644 --- a/distribution/conf/derby-schema.sql +++ b/distribution/conf/derby-schema.sql @@ -17,46 +17,46 @@ CREATE SCHEMA nacos AUTHORIZATION nacos; CREATE TABLE config_info ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - app_name varchar(128), - content CLOB, - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - src_user varchar(128) DEFAULT NULL, - src_ip varchar(50) DEFAULT NULL, - c_desc varchar(256) DEFAULT NULL, - c_use varchar(64) DEFAULT NULL, - effect varchar(64) DEFAULT NULL, - type varchar(64) DEFAULT NULL, - c_schema LONG VARCHAR DEFAULT NULL, - encrypted_data_key LONG VARCHAR DEFAULT NULL, - constraint configinfo_id_key PRIMARY KEY (id), - constraint uk_configinfo_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + app_name varchar(128), + content CLOB, + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + src_user varchar(128) DEFAULT NULL, + src_ip varchar(50) DEFAULT NULL, + c_desc varchar(256) DEFAULT NULL, + c_use varchar(64) DEFAULT NULL, + effect varchar(64) DEFAULT NULL, + type varchar(64) DEFAULT NULL, + c_schema LONG VARCHAR DEFAULT NULL, + encrypted_data_key LONG VARCHAR DEFAULT NULL, + constraint configinfo_id_key PRIMARY KEY (id), + constraint uk_configinfo_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); CREATE INDEX configinfo_dataid_key_idx ON config_info(data_id); CREATE INDEX configinfo_groupid_key_idx ON config_info(group_id); CREATE INDEX configinfo_dataid_group_key_idx ON config_info(data_id, group_id); CREATE TABLE his_config_info ( - id bigint NOT NULL, - nid bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - app_name varchar(128), - content CLOB, - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', - src_user varchar(128), - src_ip varchar(50) DEFAULT NULL, - op_type char(10) DEFAULT NULL, - encrypted_data_key LONG VARCHAR DEFAULT NULL, - constraint hisconfiginfo_nid_key PRIMARY KEY (nid)); + id bigint NOT NULL, + nid bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + app_name varchar(128), + content CLOB, + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', + src_user varchar(128), + src_ip varchar(50) DEFAULT NULL, + op_type char(10) DEFAULT NULL, + encrypted_data_key LONG VARCHAR DEFAULT NULL, + constraint hisconfiginfo_nid_key PRIMARY KEY (nid)); CREATE INDEX hisconfiginfo_dataid_key_idx ON his_config_info(data_id); CREATE INDEX hisconfiginfo_gmt_create_idx ON his_config_info(gmt_create); @@ -64,164 +64,185 @@ CREATE INDEX hisconfiginfo_gmt_modified_idx ON his_config_info(gmt_modified); CREATE TABLE config_info_beta ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - app_name varchar(128), - content CLOB, - beta_ips varchar(1024), - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - src_user varchar(128), - src_ip varchar(50) DEFAULT NULL, - encrypted_data_key LONG VARCHAR DEFAULT NULL, - constraint configinfobeta_id_key PRIMARY KEY (id), - constraint uk_configinfobeta_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + app_name varchar(128), + content CLOB, + beta_ips varchar(1024), + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + src_user varchar(128), + src_ip varchar(50) DEFAULT NULL, + encrypted_data_key LONG VARCHAR DEFAULT NULL, + constraint configinfobeta_id_key PRIMARY KEY (id), + constraint uk_configinfobeta_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); CREATE TABLE config_info_tag ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - tag_id varchar(128) NOT NULL, - app_name varchar(128), - content CLOB, - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - src_user varchar(128), - src_ip varchar(50) DEFAULT NULL, - constraint configinfotag_id_key PRIMARY KEY (id), - constraint uk_configinfotag_datagrouptenanttag UNIQUE (data_id,group_id,tenant_id,tag_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + tag_id varchar(128) NOT NULL, + app_name varchar(128), + content CLOB, + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + src_user varchar(128), + src_ip varchar(50) DEFAULT NULL, + constraint configinfotag_id_key PRIMARY KEY (id), + constraint uk_configinfotag_datagrouptenanttag UNIQUE (data_id,group_id,tenant_id,tag_id)); + +CREATE TABLE config_info_gray ( + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + gray_name varchar(128) NOT NULL, + gray_rule CLOB, + app_name varchar(128), + src_ip varchar(128), + src_user varchar(128) default '', + content CLOB, + md5 varchar(32) DEFAULT NULL, + encrypted_data_key varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + constraint configinfogray_id_key PRIMARY KEY (id), + constraint uk_configinfogray_datagrouptenantgrayname UNIQUE (data_id,group_id,tenant_id,gray_name)); +CREATE INDEX config_info_gray_dataid_gmt_modified ON config_info_gray(data_id,gmt_modified); +CREATE INDEX config_info_gray_gmt_modified ON config_info_gray(gmt_modified); CREATE TABLE config_info_aggr ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - datum_id varchar(255) NOT NULL, - app_name varchar(128), - content CLOB, - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - constraint configinfoaggr_id_key PRIMARY KEY (id), - constraint uk_configinfoaggr_datagrouptenantdatum UNIQUE (data_id,group_id,tenant_id,datum_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + datum_id varchar(255) NOT NULL, + app_name varchar(128), + content CLOB, + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + constraint configinfoaggr_id_key PRIMARY KEY (id), + constraint uk_configinfoaggr_datagrouptenantdatum UNIQUE (data_id,group_id,tenant_id,datum_id)); CREATE TABLE app_list ( - id bigint NOT NULL generated by default as identity, - app_name varchar(128) NOT NULL, - is_dynamic_collect_disabled smallint DEFAULT 0, - last_sub_info_collected_time timestamp DEFAULT '1970-01-01 08:00:00.0', - sub_info_lock_owner varchar(128), - sub_info_lock_time timestamp DEFAULT '1970-01-01 08:00:00.0', - constraint applist_id_key PRIMARY KEY (id), - constraint uk_appname UNIQUE (app_name)); + id bigint NOT NULL generated by default as identity, + app_name varchar(128) NOT NULL, + is_dynamic_collect_disabled smallint DEFAULT 0, + last_sub_info_collected_time timestamp DEFAULT '1970-01-01 08:00:00.0', + sub_info_lock_owner varchar(128), + sub_info_lock_time timestamp DEFAULT '1970-01-01 08:00:00.0', + constraint applist_id_key PRIMARY KEY (id), + constraint uk_appname UNIQUE (app_name)); CREATE TABLE app_configdata_relation_subs ( - id bigint NOT NULL generated by default as identity, - app_name varchar(128) NOT NULL, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint configdatarelationsubs_id_key PRIMARY KEY (id), - constraint uk_app_sub_config_datagroup UNIQUE (app_name, data_id, group_id)); + id bigint NOT NULL generated by default as identity, + app_name varchar(128) NOT NULL, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint configdatarelationsubs_id_key PRIMARY KEY (id), + constraint uk_app_sub_config_datagroup UNIQUE (app_name, data_id, group_id)); CREATE TABLE app_configdata_relation_pubs ( - id bigint NOT NULL generated by default as identity, - app_name varchar(128) NOT NULL, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint configdatarelationpubs_id_key PRIMARY KEY (id), - constraint uk_app_pub_config_datagroup UNIQUE (app_name, data_id, group_id)); + id bigint NOT NULL generated by default as identity, + app_name varchar(128) NOT NULL, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint configdatarelationpubs_id_key PRIMARY KEY (id), + constraint uk_app_pub_config_datagroup UNIQUE (app_name, data_id, group_id)); CREATE TABLE config_tags_relation ( - id bigint NOT NULL, - tag_name varchar(128) NOT NULL, - tag_type varchar(64) DEFAULT NULL, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) DEFAULT '', - nid bigint NOT NULL generated by default as identity, - constraint config_tags_id_key PRIMARY KEY (nid), - constraint uk_configtagrelation_configidtag UNIQUE (id, tag_name, tag_type)); + id bigint NOT NULL, + tag_name varchar(128) NOT NULL, + tag_type varchar(64) DEFAULT NULL, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) DEFAULT '', + nid bigint NOT NULL generated by default as identity, + constraint config_tags_id_key PRIMARY KEY (nid), + constraint uk_configtagrelation_configidtag UNIQUE (id, tag_name, tag_type)); CREATE INDEX config_tags_tenant_id_idx ON config_tags_relation(tenant_id); CREATE TABLE group_capacity ( - id bigint NOT NULL generated by default as identity, - group_id varchar(128) DEFAULT '', - quota int DEFAULT 0, - usage int DEFAULT 0, - max_size int DEFAULT 0, - max_aggr_count int DEFAULT 0, - max_aggr_size int DEFAULT 0, - max_history_count int DEFAULT 0, - gmt_create timestamp DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint group_capacity_id_key PRIMARY KEY (id), - constraint uk_group_id UNIQUE (group_id)); + id bigint NOT NULL generated by default as identity, + group_id varchar(128) DEFAULT '', + quota int DEFAULT 0, + usage int DEFAULT 0, + max_size int DEFAULT 0, + max_aggr_count int DEFAULT 0, + max_aggr_size int DEFAULT 0, + max_history_count int DEFAULT 0, + gmt_create timestamp DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint group_capacity_id_key PRIMARY KEY (id), + constraint uk_group_id UNIQUE (group_id)); CREATE TABLE tenant_capacity ( - id bigint NOT NULL generated by default as identity, - tenant_id varchar(128) DEFAULT '', - quota int DEFAULT 0, - usage int DEFAULT 0, - max_size int DEFAULT 0, - max_aggr_count int DEFAULT 0, - max_aggr_size int DEFAULT 0, - max_history_count int DEFAULT 0, - gmt_create timestamp DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint tenant_capacity_id_key PRIMARY KEY (id), - constraint uk_tenant_id UNIQUE (tenant_id)); + id bigint NOT NULL generated by default as identity, + tenant_id varchar(128) DEFAULT '', + quota int DEFAULT 0, + usage int DEFAULT 0, + max_size int DEFAULT 0, + max_aggr_count int DEFAULT 0, + max_aggr_size int DEFAULT 0, + max_history_count int DEFAULT 0, + gmt_create timestamp DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint tenant_capacity_id_key PRIMARY KEY (id), + constraint uk_tenant_id UNIQUE (tenant_id)); CREATE TABLE tenant_info ( - id bigint NOT NULL generated by default as identity, - kp varchar(128) NOT NULL, - tenant_id varchar(128) DEFAULT '', - tenant_name varchar(128) DEFAULT '', - tenant_desc varchar(256) DEFAULT NULL, - create_source varchar(32) DEFAULT NULL, - gmt_create bigint NOT NULL, - gmt_modified bigint NOT NULL, - constraint tenant_info_id_key PRIMARY KEY (id), - constraint uk_tenant_info_kptenantid UNIQUE (kp,tenant_id)); + id bigint NOT NULL generated by default as identity, + kp varchar(128) NOT NULL, + tenant_id varchar(128) DEFAULT '', + tenant_name varchar(128) DEFAULT '', + tenant_desc varchar(256) DEFAULT NULL, + create_source varchar(32) DEFAULT NULL, + gmt_create bigint NOT NULL, + gmt_modified bigint NOT NULL, + constraint tenant_info_id_key PRIMARY KEY (id), + constraint uk_tenant_info_kptenantid UNIQUE (kp,tenant_id)); CREATE INDEX tenant_info_tenant_id_idx ON tenant_info(tenant_id); CREATE TABLE users ( - username varchar(50) NOT NULL PRIMARY KEY, - password varchar(500) NOT NULL, - enabled boolean NOT NULL DEFAULT true + username varchar(50) NOT NULL PRIMARY KEY, + password varchar(500) NOT NULL, + enabled boolean NOT NULL DEFAULT true ); CREATE TABLE roles ( - username varchar(50) NOT NULL, - role varchar(50) NOT NULL, - constraint uk_username_role UNIQUE (username,role) + username varchar(50) NOT NULL, + role varchar(50) NOT NULL, + constraint uk_username_role UNIQUE (username,role) ); CREATE TABLE permissions ( - role varchar(50) NOT NULL, - resource varchar(512) NOT NULL, - action varchar(8) NOT NULL, - constraint uk_role_permission UNIQUE (role,resource,action) + role varchar(50) NOT NULL, + resource varchar(512) NOT NULL, + action varchar(8) NOT NULL, + constraint uk_role_permission UNIQUE (role,resource,action) ); + /******************************************/ /* ipv6 support */ /******************************************/ ALTER TABLE `config_info_tag` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; ALTER TABLE `his_config_info` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `src_user`; + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `src_user`; ALTER TABLE `config_info` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; ALTER TABLE `config_info_beta` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; \ No newline at end of file + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; \ No newline at end of file diff --git a/distribution/conf/mysql-schema.sql b/distribution/conf/mysql-schema.sql index d3c06606e13..6a879dc10cb 100644 --- a/distribution/conf/mysql-schema.sql +++ b/distribution/conf/mysql-schema.sql @@ -21,7 +21,7 @@ CREATE TABLE `config_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) DEFAULT NULL COMMENT 'group_id', - `content` longtext NOT NULL COMMENT 'content', + `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', @@ -64,7 +64,7 @@ CREATE TABLE `config_info_beta` ( `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', - `content` longtext NOT NULL COMMENT 'content', + `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'content', `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', @@ -87,7 +87,7 @@ CREATE TABLE `config_info_tag` ( `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `tag_id` varchar(128) NOT NULL COMMENT 'tag_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', - `content` longtext NOT NULL COMMENT 'content', + `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', @@ -97,6 +97,30 @@ CREATE TABLE `config_info_tag` ( UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag'; +/******************************************/ +/* 表名称 = config_info_gray */ +/******************************************/ +CREATE TABLE IF NOT EXISTS `config_info_gray` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `data_id` varchar(255) NOT NULL COMMENT 'data_id', + `group_id` varchar(128) NOT NULL COMMENT 'group_id', + `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'content', + `md5` varchar(32) DEFAULT NULL COMMENT 'md5', + `src_user` text COMMENT 'src_user', + `src_ip` varchar(100) DEFAULT NULL COMMENT 'src_ip', + `gmt_create` datetime(3) NOT NULL DEFAULT now(3) COMMENT 'gmt_create', + `gmt_modified` datetime(3) NOT NULL DEFAULT now(3) COMMENT 'gmt_modified', + `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', + `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', + `gray_name` varchar(128) NOT NULL COMMENT 'gray_name', + `gray_rule` text NOT NULL COMMENT 'gray_rule', + `encrypted_data_key` varchar(256) NOT NULL DEFAULT '' COMMENT 'encrypted_data_key', + PRIMARY KEY (`id`), + UNIQUE KEY `uk_configinfogray_datagrouptenantgray` (`data_id`,`group_id`,`tenant_id`,`gray_name`), + KEY `idx_dataid_gmt_modified` (`data_id`,`gmt_modified`), + KEY `idx_gmt_modified` (`gmt_modified`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_gray'; + /******************************************/ /* 表名称 = config_tags_relation */ /******************************************/ @@ -140,7 +164,7 @@ CREATE TABLE `his_config_info` ( `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', - `content` longtext NOT NULL COMMENT 'content', + `content` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', diff --git a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/FieldConstant.java b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/FieldConstant.java index d5c7576e90c..dc71dd48df0 100644 --- a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/FieldConstant.java +++ b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/FieldConstant.java @@ -80,6 +80,10 @@ public class FieldConstant { public static final String TAG_ID = "tagId"; + public static final String GRAY_NAME = "grayName"; + + public static final String GRAY_RULE = "grayRule"; + public static final String QUOTA = "quota"; public static final String MAX_SIZE = "maxSize"; diff --git a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/TableConstant.java b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/TableConstant.java index 8ff06df344d..0423a262d91 100644 --- a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/TableConstant.java +++ b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/TableConstant.java @@ -32,6 +32,8 @@ public class TableConstant { public static final String CONFIG_INFO_TAG = "config_info_tag"; + public static final String CONFIG_INFO_GRAY = "config_info_gray"; + public static final String CONFIG_TAGS_RELATION = "config_tags_relation"; public static final String GROUP_CAPACITY = "group_capacity"; diff --git a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/derby/ConfigInfoGrayMapperByDerby.java b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/derby/ConfigInfoGrayMapperByDerby.java new file mode 100644 index 00000000000..bb9f4c01e09 --- /dev/null +++ b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/derby/ConfigInfoGrayMapperByDerby.java @@ -0,0 +1,59 @@ +/* + * Copyright 1999-2022 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.plugin.datasource.impl.derby; + +import com.alibaba.nacos.common.utils.CollectionUtils; +import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant; +import com.alibaba.nacos.plugin.datasource.constants.FieldConstant; +import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoGrayMapper; +import com.alibaba.nacos.plugin.datasource.model.MapperContext; +import com.alibaba.nacos.plugin.datasource.model.MapperResult; + +import java.util.Collections; + +/** + * The derby implementation of ConfigInfoGrayMapper. + * + * @author rong + **/ + +public class ConfigInfoGrayMapperByDerby extends AbstractMapperByDerby implements ConfigInfoGrayMapper { + + @Override + public MapperResult findAllConfigInfoGrayForDumpAllFetchRows(MapperContext context) { + String sql = "SELECT t.id,data_id,group_id,tenant_id,gray_name,gray_rule,app_name,content,md5,gmt_modified " + + " FROM ( SELECT id FROM config_info_gray ORDER BY id OFFSET " + context.getStartRow() + + " ROWS FETCH NEXT " + context.getPageSize() + " ROWS ONLY ) " + + " g, config_info_gray t WHERE g.id = t.id"; + return new MapperResult(sql, Collections.emptyList()); + } + + @Override + public MapperResult findChangeConfig(MapperContext context) { + String sql = "SELECT id, data_id, group_id, tenant_id, app_name, content,gray_name,gray_rule, " + + "gmt_modified, encrypted_data_key FROM config_info_gray WHERE " + + "gmt_modified >= ? and id > ? order by id OFFSET 0 ROWS FETCH NEXT ? ROWS ONLY"; + return new MapperResult(sql, CollectionUtils.list(context.getWhereParameter(FieldConstant.START_TIME), + context.getWhereParameter(FieldConstant.LAST_MAX_ID), + context.getWhereParameter(FieldConstant.PAGE_SIZE))); + } + + @Override + public String getDataSource() { + return DataSourceConstant.DERBY; + } +} diff --git a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigInfoGrayMapperByMySql.java b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigInfoGrayMapperByMySql.java new file mode 100644 index 00000000000..f471da23a40 --- /dev/null +++ b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/mysql/ConfigInfoGrayMapperByMySql.java @@ -0,0 +1,46 @@ +/* + * Copyright 1999-2022 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.plugin.datasource.impl.mysql; + +import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant; +import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoGrayMapper; +import com.alibaba.nacos.plugin.datasource.model.MapperContext; +import com.alibaba.nacos.plugin.datasource.model.MapperResult; + +import java.util.Collections; + +/** + * The mysql implementation of ConfigInfoGrayMapper. + * + * @author rong + **/ + +public class ConfigInfoGrayMapperByMySql extends AbstractMapperByMysql implements ConfigInfoGrayMapper { + + @Override + public MapperResult findAllConfigInfoGrayForDumpAllFetchRows(MapperContext context) { + String sql = " SELECT t.id,data_id,group_id,tenant_id,gray_name,gray_rule,app_name,content,md5,gmt_modified " + + " FROM ( SELECT id FROM config_info_gray ORDER BY id LIMIT " + context.getStartRow() + "," + + context.getPageSize() + " ) " + "g, config_info_gray t WHERE g.id = t.id "; + return new MapperResult(sql, Collections.emptyList()); + } + + @Override + public String getDataSource() { + return DataSourceConstant.MYSQL; + } +} diff --git a/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigInfoGrayMapper.java b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigInfoGrayMapper.java new file mode 100644 index 00000000000..de2bf9dd1d0 --- /dev/null +++ b/plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/mapper/ConfigInfoGrayMapper.java @@ -0,0 +1,97 @@ +/* + * Copyright 1999-2022 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.plugin.datasource.mapper; + +import com.alibaba.nacos.common.utils.CollectionUtils; +import com.alibaba.nacos.plugin.datasource.constants.FieldConstant; +import com.alibaba.nacos.plugin.datasource.constants.TableConstant; +import com.alibaba.nacos.plugin.datasource.model.MapperContext; +import com.alibaba.nacos.plugin.datasource.model.MapperResult; + +/** + * The config gray info mapper. + * + * @author rong + **/ + +public interface ConfigInfoGrayMapper extends Mapper { + + /** + * Update gray configuration information. The default sql: UPDATE config_info_gray SET content=?, md5 = ?, + * src_ip=?,src_user=?,gmt_modified=?,app_name=?,gray_rule=? WHERE data_id=? AND group_id=? AND tenant_id=? AND + * gray_name=? AND (md5=? or md5 is null or md5='') + * + * @param context sql paramMap + * @return The sql of updating gray configuration information. + */ + default MapperResult updateConfigInfo4GrayCas(MapperContext context) { + Object content = context.getUpdateParameter(FieldConstant.CONTENT); + Object md5 = context.getUpdateParameter(FieldConstant.MD5); + Object srcIp = context.getUpdateParameter(FieldConstant.SRC_IP); + Object srcUser = context.getUpdateParameter(FieldConstant.SRC_USER); + Object gmtModified = context.getUpdateParameter(FieldConstant.GMT_MODIFIED); + Object appName = context.getUpdateParameter(FieldConstant.APP_NAME); + + Object dataId = context.getWhereParameter(FieldConstant.DATA_ID); + Object groupId = context.getWhereParameter(FieldConstant.GROUP_ID); + Object tenantId = context.getWhereParameter(FieldConstant.TENANT_ID); + Object grayName = context.getWhereParameter(FieldConstant.GRAY_NAME); + Object grayRule = context.getWhereParameter(FieldConstant.GRAY_RULE); + Object oldMd5 = context.getWhereParameter(FieldConstant.MD5); + String sql = "UPDATE config_info_gray SET content = ?, md5 = ?, src_ip = ?,src_user = ?,gmt_modified = " + + getFunction("NOW()") + ",app_name = ?, gray_rule = ?" + + "WHERE data_id = ? AND group_id = ? AND tenant_id = ? AND gray_name = ? AND (md5 = ? OR md5 IS NULL OR md5 = '')"; + return new MapperResult(sql, + CollectionUtils.list(content, md5, srcIp, srcUser, appName, grayRule, dataId, groupId, + tenantId, grayName, oldMd5)); + } + + /** + * Query change config.
The default sql: SELECT data_id, group_id, tenant_id, app_name, content, + * gmt_modified,encrypted_data_key FROM config_info WHERE gmt_modified >=? AND gmt_modified <= ? + * + * @param context sql paramMap + * @return The sql of querying change config. + */ + default MapperResult findChangeConfig(MapperContext context) { + String sql = + "SELECT id, data_id, group_id, tenant_id, app_name,content,gray_name,gray_rule,md5, gmt_modified, encrypted_data_key " + + "FROM config_info_gray WHERE " + "gmt_modified >= ? and id > ? order by id limit ? "; + return new MapperResult(sql, CollectionUtils.list(context.getWhereParameter(FieldConstant.START_TIME), + context.getWhereParameter(FieldConstant.LAST_MAX_ID), + context.getWhereParameter(FieldConstant.PAGE_SIZE))); + } + + /** + * Query all gray config info for dump task. The default sql: SELECT + * t.id,data_id,group_id,tenant_id,gray_name,app_name,content,md5,gmt_modified FROM ( SELECT id FROM + * config_info_gray ORDER BY id LIMIT startRow,pageSize ) g, config_info_gray t WHERE g.id = t.id + * + * @param context The start index. + * @return The sql of querying all gray config info for dump task. + */ + MapperResult findAllConfigInfoGrayForDumpAllFetchRows(MapperContext context); + + /** + * 获取返回表名. + * + * @return 表名 + */ + default String getTableName() { + return TableConstant.CONFIG_INFO_GRAY; + } +} diff --git a/plugin/datasource/src/main/resources/META-INF/services/com.alibaba.nacos.plugin.datasource.mapper.Mapper b/plugin/datasource/src/main/resources/META-INF/services/com.alibaba.nacos.plugin.datasource.mapper.Mapper index f0d6adeb57f..d11d4ba59eb 100644 --- a/plugin/datasource/src/main/resources/META-INF/services/com.alibaba.nacos.plugin.datasource.mapper.Mapper +++ b/plugin/datasource/src/main/resources/META-INF/services/com.alibaba.nacos.plugin.datasource.mapper.Mapper @@ -18,6 +18,7 @@ com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoAggrMapperByMySql com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoBetaMapperByMySql com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoMapperByMySql com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoTagMapperByMySql +com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoGrayMapperByMySql com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigTagsRelationMapperByMySql com.alibaba.nacos.plugin.datasource.impl.mysql.HistoryConfigInfoMapperByMySql com.alibaba.nacos.plugin.datasource.impl.mysql.TenantInfoMapperByMySql @@ -28,6 +29,7 @@ com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoAggrMapperByDerby com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoBetaMapperByDerby com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoMapperByDerby com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoTagMapperByDerby +com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoGrayMapperByDerby com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoTagsRelationMapperByDerby com.alibaba.nacos.plugin.datasource.impl.derby.HistoryConfigInfoMapperByDerby com.alibaba.nacos.plugin.datasource.impl.derby.TenantInfoMapperByDerby diff --git a/test/config-test/src/test/resources/derby-schema.sql b/test/config-test/src/test/resources/derby-schema.sql index f4e93a3aab6..c27eadf9134 100644 --- a/test/config-test/src/test/resources/derby-schema.sql +++ b/test/config-test/src/test/resources/derby-schema.sql @@ -17,46 +17,46 @@ CREATE SCHEMA nacos AUTHORIZATION nacos; CREATE TABLE config_info ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - app_name varchar(128), - content CLOB, - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - src_user varchar(128) DEFAULT NULL, - src_ip varchar(50) DEFAULT NULL, - c_desc varchar(256) DEFAULT NULL, - c_use varchar(64) DEFAULT NULL, - effect varchar(64) DEFAULT NULL, - type varchar(64) DEFAULT NULL, - c_schema LONG VARCHAR DEFAULT NULL, - encrypted_data_key LONG VARCHAR DEFAULT NULL, - constraint configinfo_id_key PRIMARY KEY (id), - constraint uk_configinfo_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + app_name varchar(128), + content CLOB, + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + src_user varchar(128) DEFAULT NULL, + src_ip varchar(50) DEFAULT NULL, + c_desc varchar(256) DEFAULT NULL, + c_use varchar(64) DEFAULT NULL, + effect varchar(64) DEFAULT NULL, + type varchar(64) DEFAULT NULL, + c_schema LONG VARCHAR DEFAULT NULL, + encrypted_data_key LONG VARCHAR DEFAULT NULL, + constraint configinfo_id_key PRIMARY KEY (id), + constraint uk_configinfo_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); CREATE INDEX configinfo_dataid_key_idx ON config_info(data_id); CREATE INDEX configinfo_groupid_key_idx ON config_info(group_id); CREATE INDEX configinfo_dataid_group_key_idx ON config_info(data_id, group_id); CREATE TABLE his_config_info ( - id bigint NOT NULL, - nid bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - app_name varchar(128), - content CLOB, - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', - src_user varchar(128), - src_ip varchar(50) DEFAULT NULL, - op_type char(10) DEFAULT NULL, - encrypted_data_key LONG VARCHAR DEFAULT NULL, - constraint hisconfiginfo_nid_key PRIMARY KEY (nid)); + id bigint NOT NULL, + nid bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + app_name varchar(128), + content CLOB, + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00.000', + src_user varchar(128), + src_ip varchar(50) DEFAULT NULL, + op_type char(10) DEFAULT NULL, + encrypted_data_key LONG VARCHAR DEFAULT NULL, + constraint hisconfiginfo_nid_key PRIMARY KEY (nid)); CREATE INDEX hisconfiginfo_dataid_key_idx ON his_config_info(data_id); CREATE INDEX hisconfiginfo_gmt_create_idx ON his_config_info(gmt_create); @@ -64,164 +64,185 @@ CREATE INDEX hisconfiginfo_gmt_modified_idx ON his_config_info(gmt_modified); CREATE TABLE config_info_beta ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - app_name varchar(128), - content CLOB, - beta_ips varchar(1024), - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - src_user varchar(128), - src_ip varchar(50) DEFAULT NULL, - encrypted_data_key LONG VARCHAR DEFAULT NULL, - constraint configinfobeta_id_key PRIMARY KEY (id), - constraint uk_configinfobeta_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + app_name varchar(128), + content CLOB, + beta_ips varchar(1024), + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + src_user varchar(128), + src_ip varchar(50) DEFAULT NULL, + encrypted_data_key LONG VARCHAR DEFAULT NULL, + constraint configinfobeta_id_key PRIMARY KEY (id), + constraint uk_configinfobeta_datagrouptenant UNIQUE (data_id,group_id,tenant_id)); CREATE TABLE config_info_tag ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - tag_id varchar(128) NOT NULL, - app_name varchar(128), - content CLOB, - md5 varchar(32) DEFAULT NULL, - gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - src_user varchar(128), - src_ip varchar(50) DEFAULT NULL, - constraint configinfotag_id_key PRIMARY KEY (id), - constraint uk_configinfotag_datagrouptenanttag UNIQUE (data_id,group_id,tenant_id,tag_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + tag_id varchar(128) NOT NULL, + app_name varchar(128), + content CLOB, + md5 varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + src_user varchar(128), + src_ip varchar(50) DEFAULT NULL, + constraint configinfotag_id_key PRIMARY KEY (id), + constraint uk_configinfotag_datagrouptenanttag UNIQUE (data_id,group_id,tenant_id,tag_id)); + +CREATE TABLE config_info_gray ( + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + gray_name varchar(128) NOT NULL, + gray_rule CLOB, + app_name varchar(128), + src_ip varchar(128), + src_user varchar(128) default '', + content CLOB, + md5 varchar(32) DEFAULT NULL, + encrypted_data_key varchar(32) DEFAULT NULL, + gmt_create timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + constraint configinfogray_id_key PRIMARY KEY (id), + constraint uk_configinfogray_datagrouptenantgrayname UNIQUE (data_id,group_id,tenant_id,gray_name)); +CREATE INDEX config_info_gray_dataid_gmt_modified ON config_info_gray(data_id,gmt_modified); +CREATE INDEX config_info_gray_gmt_modified ON config_info_gray(gmt_modified); CREATE TABLE config_info_aggr ( - id bigint NOT NULL generated by default as identity, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) default '', - datum_id varchar(255) NOT NULL, - app_name varchar(128), - content CLOB, - gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', - constraint configinfoaggr_id_key PRIMARY KEY (id), - constraint uk_configinfoaggr_datagrouptenantdatum UNIQUE (data_id,group_id,tenant_id,datum_id)); + id bigint NOT NULL generated by default as identity, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) default '', + datum_id varchar(255) NOT NULL, + app_name varchar(128), + content CLOB, + gmt_modified timestamp NOT NULL DEFAULT '2010-05-05 00:00:00', + constraint configinfoaggr_id_key PRIMARY KEY (id), + constraint uk_configinfoaggr_datagrouptenantdatum UNIQUE (data_id,group_id,tenant_id,datum_id)); CREATE TABLE app_list ( - id bigint NOT NULL generated by default as identity, - app_name varchar(128) NOT NULL, - is_dynamic_collect_disabled smallint DEFAULT 0, - last_sub_info_collected_time timestamp DEFAULT '1970-01-01 08:00:00.0', - sub_info_lock_owner varchar(128), - sub_info_lock_time timestamp DEFAULT '1970-01-01 08:00:00.0', - constraint applist_id_key PRIMARY KEY (id), - constraint uk_appname UNIQUE (app_name)); + id bigint NOT NULL generated by default as identity, + app_name varchar(128) NOT NULL, + is_dynamic_collect_disabled smallint DEFAULT 0, + last_sub_info_collected_time timestamp DEFAULT '1970-01-01 08:00:00.0', + sub_info_lock_owner varchar(128), + sub_info_lock_time timestamp DEFAULT '1970-01-01 08:00:00.0', + constraint applist_id_key PRIMARY KEY (id), + constraint uk_appname UNIQUE (app_name)); CREATE TABLE app_configdata_relation_subs ( - id bigint NOT NULL generated by default as identity, - app_name varchar(128) NOT NULL, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint configdatarelationsubs_id_key PRIMARY KEY (id), - constraint uk_app_sub_config_datagroup UNIQUE (app_name, data_id, group_id)); + id bigint NOT NULL generated by default as identity, + app_name varchar(128) NOT NULL, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint configdatarelationsubs_id_key PRIMARY KEY (id), + constraint uk_app_sub_config_datagroup UNIQUE (app_name, data_id, group_id)); CREATE TABLE app_configdata_relation_pubs ( - id bigint NOT NULL generated by default as identity, - app_name varchar(128) NOT NULL, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint configdatarelationpubs_id_key PRIMARY KEY (id), - constraint uk_app_pub_config_datagroup UNIQUE (app_name, data_id, group_id)); + id bigint NOT NULL generated by default as identity, + app_name varchar(128) NOT NULL, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint configdatarelationpubs_id_key PRIMARY KEY (id), + constraint uk_app_pub_config_datagroup UNIQUE (app_name, data_id, group_id)); CREATE TABLE config_tags_relation ( - id bigint NOT NULL, - tag_name varchar(128) NOT NULL, - tag_type varchar(64) DEFAULT NULL, - data_id varchar(255) NOT NULL, - group_id varchar(128) NOT NULL, - tenant_id varchar(128) DEFAULT '', - nid bigint NOT NULL generated by default as identity, - constraint config_tags_id_key PRIMARY KEY (nid), - constraint uk_configtagrelation_configidtag UNIQUE (id, tag_name, tag_type)); + id bigint NOT NULL, + tag_name varchar(128) NOT NULL, + tag_type varchar(64) DEFAULT NULL, + data_id varchar(255) NOT NULL, + group_id varchar(128) NOT NULL, + tenant_id varchar(128) DEFAULT '', + nid bigint NOT NULL generated by default as identity, + constraint config_tags_id_key PRIMARY KEY (nid), + constraint uk_configtagrelation_configidtag UNIQUE (id, tag_name, tag_type)); CREATE INDEX config_tags_tenant_id_idx ON config_tags_relation(tenant_id); CREATE TABLE group_capacity ( - id bigint NOT NULL generated by default as identity, - group_id varchar(128) DEFAULT '', - quota int DEFAULT 0, - usage int DEFAULT 0, - max_size int DEFAULT 0, - max_aggr_count int DEFAULT 0, - max_aggr_size int DEFAULT 0, - max_history_count int DEFAULT 0, - gmt_create timestamp DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint group_capacity_id_key PRIMARY KEY (id), - constraint uk_group_id UNIQUE (group_id)); + id bigint NOT NULL generated by default as identity, + group_id varchar(128) DEFAULT '', + quota int DEFAULT 0, + usage int DEFAULT 0, + max_size int DEFAULT 0, + max_aggr_count int DEFAULT 0, + max_aggr_size int DEFAULT 0, + max_history_count int DEFAULT 0, + gmt_create timestamp DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint group_capacity_id_key PRIMARY KEY (id), + constraint uk_group_id UNIQUE (group_id)); CREATE TABLE tenant_capacity ( - id bigint NOT NULL generated by default as identity, - tenant_id varchar(128) DEFAULT '', - quota int DEFAULT 0, - usage int DEFAULT 0, - max_size int DEFAULT 0, - max_aggr_count int DEFAULT 0, - max_aggr_size int DEFAULT 0, - max_history_count int DEFAULT 0, - gmt_create timestamp DEFAULT '2010-05-05 00:00:00', - gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', - constraint tenant_capacity_id_key PRIMARY KEY (id), - constraint uk_tenant_id UNIQUE (tenant_id)); + id bigint NOT NULL generated by default as identity, + tenant_id varchar(128) DEFAULT '', + quota int DEFAULT 0, + usage int DEFAULT 0, + max_size int DEFAULT 0, + max_aggr_count int DEFAULT 0, + max_aggr_size int DEFAULT 0, + max_history_count int DEFAULT 0, + gmt_create timestamp DEFAULT '2010-05-05 00:00:00', + gmt_modified timestamp DEFAULT '2010-05-05 00:00:00', + constraint tenant_capacity_id_key PRIMARY KEY (id), + constraint uk_tenant_id UNIQUE (tenant_id)); CREATE TABLE tenant_info ( - id bigint NOT NULL generated by default as identity, - kp varchar(128) NOT NULL, - tenant_id varchar(128) DEFAULT '', - tenant_name varchar(128) DEFAULT '', - tenant_desc varchar(256) DEFAULT NULL, - create_source varchar(32) DEFAULT NULL, - gmt_create bigint NOT NULL, - gmt_modified bigint NOT NULL, - constraint tenant_info_id_key PRIMARY KEY (id), - constraint uk_tenant_info_kptenantid UNIQUE (kp,tenant_id)); + id bigint NOT NULL generated by default as identity, + kp varchar(128) NOT NULL, + tenant_id varchar(128) DEFAULT '', + tenant_name varchar(128) DEFAULT '', + tenant_desc varchar(256) DEFAULT NULL, + create_source varchar(32) DEFAULT NULL, + gmt_create bigint NOT NULL, + gmt_modified bigint NOT NULL, + constraint tenant_info_id_key PRIMARY KEY (id), + constraint uk_tenant_info_kptenantid UNIQUE (kp,tenant_id)); CREATE INDEX tenant_info_tenant_id_idx ON tenant_info(tenant_id); CREATE TABLE users ( - username varchar(50) NOT NULL PRIMARY KEY, - password varchar(500) NOT NULL, - enabled boolean NOT NULL DEFAULT true + username varchar(50) NOT NULL PRIMARY KEY, + password varchar(500) NOT NULL, + enabled boolean NOT NULL DEFAULT true ); CREATE TABLE roles ( - username varchar(50) NOT NULL, - role varchar(50) NOT NULL, - constraint uk_username_role UNIQUE (username,role) + username varchar(50) NOT NULL, + role varchar(50) NOT NULL, + constraint uk_username_role UNIQUE (username,role) ); CREATE TABLE permissions ( - role varchar(50) NOT NULL, - resource varchar(512) NOT NULL, - action varchar(8) NOT NULL, - constraint uk_role_permission UNIQUE (role,resource,action) + role varchar(50) NOT NULL, + resource varchar(512) NOT NULL, + action varchar(8) NOT NULL, + constraint uk_role_permission UNIQUE (role,resource,action) ); + /******************************************/ /* ipv6 support */ /******************************************/ ALTER TABLE `config_info_tag` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; ALTER TABLE `his_config_info` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `src_user`; + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `src_user`; ALTER TABLE `config_info` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; ALTER TABLE `config_info_beta` -MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; \ No newline at end of file + MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`; \ No newline at end of file From 8af465ad0d02d99a2a135eb913c6bc73060ec66c Mon Sep 17 00:00:00 2001 From: Matthew Date: Tue, 8 Oct 2024 11:13:34 +0800 Subject: [PATCH 2/8] [ISSUE#12217] Add the reconciliation mechanism of gray configuration (#12507) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refine the formal configuration and add additional information(#12217) * Change the "configType" field to "publishType"(#12217) * Improve the gray configuration(#12217) * add the reconciliation mechanism of gray configuration(#12217) * Change the JSON format of gray rule.(#12217) * Remove redundant queries(#12217) * fix reconciliation mechanism of gray configuration.(#12217) * Adjust the way of obtaining grayName.(#12217) * Change the variable name.(#12217) --- .../config/server/constant/Constants.java | 18 + .../server/controller/ConfigController.java | 4 +- .../server/model/ConfigAllInfo4Gray.java | 97 ++++ .../server/model/ConfigHistoryInfo.java | 20 + .../server/model/ConfigInfoStateWrapper.java | 10 + .../model/gray/ConfigGrayPersistInfo.java | 2 +- .../service/ConfigOperationService.java | 2 +- .../service/dump/DumpChangeConfigWorker.java | 6 +- .../dump/DumpChangeGrayConfigWorker.java | 39 +- .../server/service/dump/DumpService.java | 2 +- .../ConfigInfoGrayPersistService.java | 85 ++- .../repository/ConfigInfoPersistService.java | 4 +- .../repository/ConfigRowMapperInjector.java | 45 ++ .../HistoryConfigInfoPersistService.java | 25 +- ...eddedConfigInfoGrayPersistServiceImpl.java | 118 +++- .../EmbeddedConfigInfoPersistServiceImpl.java | 84 +-- ...edHistoryConfigInfoPersistServiceImpl.java | 33 +- ...ernalConfigInfoGrayPersistServiceImpl.java | 259 ++++++--- .../ExternalConfigInfoPersistServiceImpl.java | 67 +-- ...alHistoryConfigInfoPersistServiceImpl.java | 36 +- .../sql/EmbeddedStorageContextUtils.java | 7 +- .../server/utils/ConfigExtInfoUtil.java | 186 +++++++ .../controller/ConfigControllerTest.java | 8 +- .../dump/DumpChangeConfigWorkerTest.java | 6 +- .../dump/DumpChangeGrayConfigWorkerTest.java | 6 +- ...dConfigInfoGrayPersistServiceImplTest.java | 83 ++- ...eddedConfigInfoPersistServiceImplTest.java | 114 ++-- ...storyConfigInfoPersistServiceImplTest.java | 29 +- ...lConfigInfoGrayPersistServiceImplTest.java | 101 ++-- ...ernalConfigInfoPersistServiceImplTest.java | 151 ++--- ...storyConfigInfoPersistServiceImplTest.java | 36 +- console-ui/src/locales/en-US.js | 8 + console-ui/src/locales/zh-CN.js | 8 + .../ConfigRollback/ConfigRollback.js | 9 + .../HistoryDetail/HistoryDetail.js | 28 + .../HistoryRollback/HistoryRollback.js | 27 +- .../static/console-ui/public/css/main.css | 524 ++++++++++++++++++ .../static/console-ui/public/js/main.js | 340 ++++++++++++ console/src/main/resources/static/index.html | 4 +- console/src/main/resources/static/js/main.js | 32 +- distribution/conf/derby-schema.sql | 2 + distribution/conf/mysql-schema.sql | 2 + .../datasource/constants/FieldConstant.java | 2 + .../derby/HistoryConfigInfoMapperByDerby.java | 11 +- .../mysql/HistoryConfigInfoMapperByMySql.java | 4 +- .../mapper/HistoryConfigInfoMapper.java | 8 +- .../HistoryConfigInfoMapperByDerbyTest.java | 11 +- .../HistoryConfigInfoMapperByMySqlTest.java | 10 +- 48 files changed, 2254 insertions(+), 459 deletions(-) create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAllInfo4Gray.java create mode 100644 config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExtInfoUtil.java create mode 100644 console/src/main/resources/static/console-ui/public/css/main.css create mode 100644 console/src/main/resources/static/console-ui/public/js/main.js diff --git a/config/src/main/java/com/alibaba/nacos/config/server/constant/Constants.java b/config/src/main/java/com/alibaba/nacos/config/server/constant/Constants.java index a0e568a0ef8..40e6fd6745b 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/constant/Constants.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/constant/Constants.java @@ -290,6 +290,17 @@ public class Constants { public static final String CONFIG_SEARCH_ACCURATE = "accurate"; + /** + * Gray rule. + */ + public static final String GRAY_RULE_TYPE = "type"; + + public static final String GRAY_RULE_EXPR = "expr"; + + public static final String GRAY_RULE_VERSION = "version"; + + public static final String GRAY_RULE_PRIORITY = "priority"; + /** * default nacos encode. */ @@ -297,6 +308,13 @@ public class Constants { public static final String NACOS_PERSIST_ENCODE_KEY = "nacosPersistEncodingKey"; + /** + * config publish type. + */ + public static final String FORMAL = "formal"; + + public static final String GRAY = "gray"; + static String getPersistEncode() { String persistEncode = System.getenv(NACOS_PERSIST_ENCODE_KEY); if (StringUtils.isBlank(persistEncode)) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java index 8165b1b0dd2..7b3de41519a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/controller/ConfigController.java @@ -314,11 +314,11 @@ public RestResult deleteConfigs(HttpServletRequest request, @RequestPar String clientIp = RequestUtil.getRemoteIp(request); String srcUser = RequestUtil.getSrcUserName(request); final Timestamp time = TimeUtils.getCurrentTime(); - List configInfoList = configInfoPersistService.removeConfigInfoByIds(ids, clientIp, srcUser); + List configInfoList = configInfoPersistService.removeConfigInfoByIds(ids, clientIp, srcUser); if (CollectionUtils.isEmpty(configInfoList)) { return RestResultUtils.success(true); } - for (ConfigInfo configInfo : configInfoList) { + for (ConfigAllInfo configInfo : configInfoList) { ConfigChangePublisher.notifyConfigChange( new ConfigDataChangeEvent(false, configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant(), time.getTime())); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAllInfo4Gray.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAllInfo4Gray.java new file mode 100644 index 00000000000..aca527d7c49 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigAllInfo4Gray.java @@ -0,0 +1,97 @@ +/* + * Copyright 1999-$toady.year Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.model; + +/** + * ConfigAllInfo4Gray. + * + * @author Nacos + */ +public class ConfigAllInfo4Gray extends ConfigInfo { + + private static final long serialVersionUID = -7926709237557990936L; + + private String srcUser; + + private String srcIp; + + private long gmtCreate; + + private long gmtModified; + + private String grayName; + + private String grayRule; + + public String getSrcUser() { + return srcUser; + } + + public void setSrcUser(String srcUser) { + this.srcUser = srcUser; + } + + public String getSrcIp() { + return srcIp; + } + + public void setSrcIp(String srcIp) { + this.srcIp = srcIp; + } + + public long getGmtCreate() { + return gmtCreate; + } + + public void setGmtCreate(long gmtCreate) { + this.gmtCreate = gmtCreate; + } + + public long getGmtModified() { + return gmtModified; + } + + public void setGmtModified(long gmtModified) { + this.gmtModified = gmtModified; + } + + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + + public String getGrayRule() { + return grayRule; + } + + public void setGrayRule(String grayRule) { + this.grayRule = grayRule; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } +} diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java index d99505af8a6..957e097f3db 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigHistoryInfo.java @@ -58,6 +58,10 @@ public class ConfigHistoryInfo implements Serializable { */ private String opType; + private String publishType; + + private String extInfo; + private Timestamp createdTime; private Timestamp lastModifiedTime; @@ -136,6 +140,22 @@ public void setOpType(String opType) { this.opType = opType; } + public String getPublishType() { + return publishType; + } + + public void setPublishType(String publishType) { + this.publishType = publishType; + } + + public String getExtInfo() { + return extInfo; + } + + public void setExtInfo(String extInfo) { + this.extInfo = extInfo; + } + public Timestamp getCreatedTime() { return new Timestamp(createdTime.getTime()); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java index 8bc146cb63f..3fd5e6a7a82 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/ConfigInfoStateWrapper.java @@ -38,6 +38,8 @@ public class ConfigInfoStateWrapper implements Serializable { private String md5; + private String grayName; + public long getId() { return id; } @@ -78,6 +80,14 @@ public void setTenant(String tenant) { this.tenant = tenant; } + public String getGrayName() { + return grayName; + } + + public void setGrayName(String grayName) { + this.grayName = grayName; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java index c8539ab619f..fc7d1cdc50c 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/model/gray/ConfigGrayPersistInfo.java @@ -23,7 +23,7 @@ * @date 2024-03-14 10:57 */ public class ConfigGrayPersistInfo { - + private String type; private String version; diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java index f21e6fbaadb..a977d9a3828 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/ConfigOperationService.java @@ -110,7 +110,7 @@ public Boolean publishConfig(ConfigForm configForm, ConfigRequestInfo configRequ configInfo.setEncryptedDataKey(encryptedDataKey); ConfigOperateResult configOperateResult; - //beta public + //beta publish if (StringUtils.isNotBlank(configRequestInfo.getBetaIps())) { configForm.setGrayName(BetaGrayRule.TYPE_BETA); configForm.setGrayRuleExp(configRequestInfo.getBetaIps()); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java index 90bec3e9884..d3a05b740da 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorker.java @@ -82,14 +82,14 @@ public void run() { while (true) { List configDeleted = historyConfigInfoPersistService.findDeletedConfig(startTime, - deleteCursorId, pageSize); + deleteCursorId, pageSize, Constants.FORMAL); for (ConfigInfoStateWrapper configInfo : configDeleted) { if (configInfoPersistService.findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()) == null) { ConfigCacheService.remove(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); - LogUtil.DEFAULT_LOG.info("[dump-delete-ok] {}", - new Object[] {GroupKey2.getKey(configInfo.getDataId(), configInfo.getGroup())}); + LogUtil.DEFAULT_LOG.info("[dump-delete-ok], groupKey: {}, tenant: {}", + new Object[] {GroupKey2.getKey(configInfo.getDataId(), configInfo.getGroup())}, configInfo.getTenant()); } } if (configDeleted.size() < pageSize) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java index ebb42754631..5aa3b76c600 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorker.java @@ -17,10 +17,13 @@ package com.alibaba.nacos.config.server.service.dump; import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.constant.Constants; import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; +import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.GroupKey2; import com.alibaba.nacos.config.server.utils.LogUtil; @@ -41,17 +44,20 @@ public class DumpChangeGrayConfigWorker implements Runnable { ConfigInfoGrayPersistService configInfoGrayPersistService; + private final HistoryConfigInfoPersistService historyConfigInfoPersistService; + int pageSize = 100; - public DumpChangeGrayConfigWorker(ConfigInfoGrayPersistService configInfoGrayPersistService, Timestamp startTime) { + public DumpChangeGrayConfigWorker(ConfigInfoGrayPersistService configInfoGrayPersistService, Timestamp startTime, + HistoryConfigInfoPersistService historyConfigInfoPersistService) { this.configInfoGrayPersistService = configInfoGrayPersistService; this.startTime = startTime; + this.historyConfigInfoPersistService = historyConfigInfoPersistService; } @Override public void run() { try { - if (!PropertyUtil.isDumpChangeOn()) { LogUtil.DEFAULT_LOG.info("DumpGrayChange task is not open"); return; @@ -59,6 +65,35 @@ public void run() { Timestamp currentTime = new Timestamp(System.currentTimeMillis()); LogUtil.DEFAULT_LOG.info("DumpGrayChange start ,from time {},current time {}", startTime, currentTime); + LogUtil.DEFAULT_LOG.info("Start to check delete configs from time {}", startTime); + long startDeletedConfigTime = System.currentTimeMillis(); + long deleteCursorId = 0L; + while (true) { + List configDeleted = historyConfigInfoPersistService.findDeletedConfig(startTime, + deleteCursorId, pageSize, Constants.GRAY); + for (ConfigInfoStateWrapper configInfo : configDeleted) { + String grayName = configInfo.getGrayName(); + if (StringUtils.isBlank(grayName)) { + continue; + } + + ConfigInfoStateWrapper configInfoStateWrapper = configInfoGrayPersistService.findConfigInfo4GrayState(configInfo.getDataId(), + configInfo.getGroup(), configInfo.getTenant(), grayName); + if (configInfoStateWrapper == null) { + ConfigCacheService.removeGray(configInfo.getDataId(), configInfo.getGroup(), + configInfo.getTenant(), grayName); + LogUtil.DEFAULT_LOG.info("[dump-gray-delete-ok], groupKey: {}, tenant: {}, grayName: {}", + GroupKey2.getKey(configInfo.getDataId(), configInfo.getGroup()), configInfo.getTenant(), grayName); + } + } + if (configDeleted.size() < pageSize) { + break; + } + deleteCursorId = configDeleted.get(configDeleted.size() - 1).getId(); + } + LogUtil.DEFAULT_LOG.info("Check delete configs finished,cost:{}", + System.currentTimeMillis() - startDeletedConfigTime); + LogUtil.DEFAULT_LOG.info("Check changeGrayConfig start"); long startChangeConfigTime = System.currentTimeMillis(); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java index b03fb229dff..ce0ee3a5a73 100755 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/dump/DumpService.java @@ -267,7 +267,7 @@ protected void dumpOperate() throws NacosException { currentTime), random.nextInt((int) PropertyUtil.getDumpChangeWorkerInterval()), TimeUnit.MILLISECONDS); ConfigExecutor.scheduleConfigChangeTask( - new DumpChangeGrayConfigWorker(this.configInfoGrayPersistService, currentTime), + new DumpChangeGrayConfigWorker(this.configInfoGrayPersistService, currentTime, this.historyConfigInfoPersistService), random.nextInt((int) PropertyUtil.getDumpChangeWorkerInterval()), TimeUnit.MILLISECONDS); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java index 7982be1582f..6fc62165c55 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoGrayPersistService.java @@ -16,6 +16,7 @@ package com.alibaba.nacos.config.server.service.repository; +import com.alibaba.nacos.config.server.model.ConfigAllInfo4Gray; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; @@ -48,9 +49,9 @@ public interface ConfigInfoGrayPersistService { /** * get gray config info state. * - * @param dataId dataId. - * @param group group. - * @param tenant tenant. + * @param dataId dataId. + * @param group group. + * @param tenant tenant. * @param grayName gray name. * @return config info state. */ @@ -60,24 +61,38 @@ ConfigInfoStateWrapper findConfigInfo4GrayState(final String dataId, final Strin /** * Add gray configuration information and publish data change events. * - * @param configInfo config info - * @param grayName gray name - * @param grayRule gray rule - * @param srcIp remote ip - * @param srcUser user + * @param configInfo config info + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip + * @param srcUser user * @return config operation result. */ ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser); + /** + * Adds configuration information with database atomic operations, minimizing SQL actions and avoiding business + * encapsulation. + * + * @param configGrayId the ID for the gray configuration + * @param configInfo the configuration information to be added + * @param grayName the name of the gray configuration + * @param grayRule the rule of the gray configuration + * @param srcIp the IP address of the source + * @param srcUser the user who performs the addition + */ + void addConfigInfoGrayAtomic(final long configGrayId, final ConfigInfo configInfo, final String grayName, final String grayRule, + final String srcIp, final String srcUser); + /** * insert or update gray config. * - * @param configInfo config info - * @param grayName gray name - * @param grayRule gray rule - * @param srcIp remote ip - * @param srcUser user + * @param configInfo config info + * @param grayName gray name + * @param grayRule gray rule + * @param srcIp remote ip + * @param srcUser user * @return config operation result. */ ConfigOperateResult insertOrUpdateGray(final ConfigInfo configInfo, final String grayName, final String grayRule, @@ -87,8 +102,8 @@ ConfigOperateResult insertOrUpdateGray(final ConfigInfo configInfo, final String * insert or update gray config cas. * * @param configInfo config info. - * @param grayName gray name - * @param grayRule gray rule + * @param grayName gray name + * @param grayRule gray rule * @param srcIp remote ip. * @param srcUser user. * @return config operation result. @@ -100,12 +115,12 @@ ConfigOperateResult insertOrUpdateGrayCas(final ConfigInfo configInfo, final Str /** * Delete configuration; database atomic operation, minimum SQL action, no business encapsulation. * - * @param dataId dataId - * @param group group - * @param tenant tenant + * @param dataId dataId + * @param group group + * @param tenant tenant * @param grayName gray name - * @param srcIp remote ip - * @param srcUser user + * @param srcIp remote ip + * @param srcUser user */ void removeConfigInfoGray(final String dataId, final String group, final String tenant, final String grayName, final String srcIp, final String srcUser); @@ -115,8 +130,8 @@ void removeConfigInfoGray(final String dataId, final String group, final String * Update gray configuration information. * * @param configInfo config info - * @param grayName gray name - * @param grayRule gray rule + * @param grayName gray name + * @param grayRule gray rule * @param srcIp remote ip * @param srcUser user * @return config operation result. @@ -128,8 +143,8 @@ ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String grayName * Update gray configuration information. * * @param configInfo config info - * @param grayName gray name - * @param grayRule gray rule + * @param grayName gray name + * @param grayRule gray rule * @param srcIp remote ip * @param srcUser user * @return success or not. @@ -141,15 +156,27 @@ ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, String grayN /** * Query gray configuration information based on dataId and group. * - * @param dataId data id - * @param group group - * @param tenant tenant + * @param dataId data id + * @param group group + * @param tenant tenant * @param grayName gray name * @return {@link com.alibaba.nacos.config.server.model.ConfigInfo4Gray} */ ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String group, final String tenant, final String grayName); + /** + * Query all gray configuration information based on dataId and group. + * + * @param dataId dataId + * @param group group + * @param tenant tenant + * @param grayName gray name + * @return all gray config info + */ + ConfigAllInfo4Gray findConfigAllInfo4Gray(final String dataId, final String group, final String tenant, + final String grayName); + /** * Returns the number of gray configuration items. * @@ -169,9 +196,9 @@ ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String grou /** * Query all gray config info for dump task. * - * @param startTime startTime + * @param startTime startTime * @param lastMaxId lastMaxId - * @param pageSize pageSize + * @param pageSize pageSize * @return {@link Page} with {@link ConfigInfoWrapper} generation */ List findChangeConfig(final Timestamp startTime, long lastMaxId, final int pageSize); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java index afb006529e0..d182900fa2a 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigInfoPersistService.java @@ -169,10 +169,10 @@ void removeConfigInfo(final String dataId, final String group, final String tena * @param ids id list * @param srcIp remote ip * @param srcUser user - * @return {@link ConfigInfo} list + * @return {@link ConfigAllInfo} list * @author klw */ - List removeConfigInfoByIds(final List ids, final String srcIp, final String srcUser); + List removeConfigInfoByIds(final List ids, final String srcIp, final String srcUser); /** * Delete tag. diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java index 62118ed3d97..f604776f135 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/ConfigRowMapperInjector.java @@ -18,6 +18,7 @@ import com.alibaba.nacos.config.server.model.ConfigAdvanceInfo; import com.alibaba.nacos.config.server.model.ConfigAllInfo; +import com.alibaba.nacos.config.server.model.ConfigAllInfo4Gray; import com.alibaba.nacos.config.server.model.ConfigHistoryInfo; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfo4Beta; @@ -58,6 +59,8 @@ public class ConfigRowMapperInjector { public static final ConfigInfoGrayWrapperRowMapper CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER = new ConfigInfoGrayWrapperRowMapper(); + public static final ConfigAllInfoGrayRowMapper CONFIG_ALL_INFO_GRAY_ROW_MAPPER = new ConfigAllInfoGrayRowMapper(); + public static final ConfigInfoRowMapper CONFIG_INFO_ROW_MAPPER = new ConfigInfoRowMapper(); public static final ConfigAdvanceInfoRowMapper CONFIG_ADVANCE_INFO_ROW_MAPPER = new ConfigAdvanceInfoRowMapper(); @@ -341,6 +344,44 @@ public ConfigInfoGrayWrapper mapRow(ResultSet rs, int rowNum) throws SQLExceptio } } + public static final class ConfigAllInfoGrayRowMapper implements RowMapper { + + @Override + public ConfigAllInfo4Gray mapRow(ResultSet rs, int rowNum) throws SQLException { + ConfigAllInfo4Gray info = new ConfigAllInfo4Gray(); + + info.setDataId(rs.getString("data_id")); + info.setGroup(rs.getString("group_id")); + info.setTenant(rs.getString("tenant_id")); + info.setGrayName(rs.getString("gray_name")); + info.setGrayRule(rs.getString("gray_rule")); + info.setAppName(rs.getString("app_name")); + info.setSrcUser(rs.getString("src_user")); + info.setSrcIp(rs.getString("src_ip")); + info.setGmtCreate(rs.getTimestamp("gmt_create").getTime()); + info.setGmtModified(rs.getTimestamp("gmt_modified").getTime()); + + try { + info.setContent(rs.getString("content")); + } catch (SQLException ignore) { + } + try { + info.setId(rs.getLong("id")); + } catch (SQLException ignore) { + } + try { + info.setMd5(rs.getString("md5")); + } catch (SQLException ignore) { + } + try { + info.setEncryptedDataKey(rs.getString("encrypted_data_key")); + } catch (SQLException ignore) { + } + + return info; + } + } + public static final class ConfigInfoRowMapper implements RowMapper { @Override @@ -564,6 +605,8 @@ public ConfigHistoryInfo mapRow(ResultSet rs, int rowNum) throws SQLException { configHistoryInfo.setSrcIp(rs.getString("src_ip")); configHistoryInfo.setSrcUser(rs.getString("src_user")); configHistoryInfo.setOpType(rs.getString("op_type")); + configHistoryInfo.setPublishType(rs.getString("publish_type")); + configHistoryInfo.setExtInfo(rs.getString("ext_info")); configHistoryInfo.setCreatedTime(rs.getTimestamp("gmt_create")); configHistoryInfo.setLastModifiedTime(rs.getTimestamp("gmt_modified")); return configHistoryInfo; @@ -585,6 +628,8 @@ public ConfigHistoryInfo mapRow(ResultSet rs, int rowNum) throws SQLException { configHistoryInfo.setSrcUser(rs.getString("src_user")); configHistoryInfo.setSrcIp(rs.getString("src_ip")); configHistoryInfo.setOpType(rs.getString("op_type")); + configHistoryInfo.setPublishType(rs.getString("publish_type")); + configHistoryInfo.setExtInfo(rs.getString("ext_info")); configHistoryInfo.setCreatedTime(rs.getTimestamp("gmt_create")); configHistoryInfo.setLastModifiedTime(rs.getTimestamp("gmt_modified")); try { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/HistoryConfigInfoPersistService.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/HistoryConfigInfoPersistService.java index e0e14b71568..3b64db45064 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/HistoryConfigInfoPersistService.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/HistoryConfigInfoPersistService.java @@ -45,15 +45,17 @@ public interface HistoryConfigInfoPersistService { /** * Update change records; database atomic operations, minimal sql actions, no business encapsulation. * - * @param id id - * @param configInfo config info - * @param srcIp ip - * @param srcUser user - * @param time time - * @param ops ops type + * @param id id + * @param configInfo config info + * @param srcIp ip + * @param srcUser user + * @param time time + * @param ops ops type + * @param publishType publish type + * @param extInfo extra config info */ void insertConfigHistoryAtomic(long id, ConfigInfo configInfo, String srcIp, String srcUser, final Timestamp time, - String ops); + String ops, String publishType, String extInfo); //------------------------------------------delete---------------------------------------------// /** @@ -69,12 +71,13 @@ void insertConfigHistoryAtomic(long id, ConfigInfo configInfo, String srcIp, Str /** * Query deleted config. * - * @param startTime start time - * @param startId last max id - * @param size page size + * @param startTime start time + * @param startId last max id + * @param size page size + * @param publishType publish type * @return {@link ConfigInfoStateWrapper} list */ - List findDeletedConfig(final Timestamp startTime, final long startId, int size); + List findDeletedConfig(final Timestamp startTime, final long startId, int size, String publishType); /** * List configuration history change record. diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java index 3a1e952a6a8..0b1c15a3127 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImpl.java @@ -20,13 +20,17 @@ import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigAllInfo4Gray; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.config.server.utils.LogUtil; +import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; @@ -44,6 +48,7 @@ import com.alibaba.nacos.plugin.datasource.model.MapperContext; import com.alibaba.nacos.plugin.datasource.model.MapperResult; import com.alibaba.nacos.sys.env.EnvUtil; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Conditional; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Service; @@ -53,6 +58,7 @@ import java.util.Collections; import java.util.List; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_GRAY_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; @@ -66,19 +72,32 @@ @Service("embeddedConfigInfoGrayPersistServiceImpl") public class EmbeddedConfigInfoGrayPersistServiceImpl implements ConfigInfoGrayPersistService { + private static final String RESOURCE_CONFIG_HISTORY_ID = "config-history-id"; + + private static final String RESOURCE_CONFIG_HISTORY_GRAY_ID = "config-history-gray-id"; + private DataSourceService dataSourceService; private final DatabaseOperate databaseOperate; private MapperManager mapperManager; + private final IdGeneratorManager idGeneratorManager; + + private final HistoryConfigInfoPersistService historyConfigInfoPersistService; + /** * The constructor sets the dependency injection order. * * @param databaseOperate databaseOperate. */ - public EmbeddedConfigInfoGrayPersistServiceImpl(DatabaseOperate databaseOperate) { + public EmbeddedConfigInfoGrayPersistServiceImpl(DatabaseOperate databaseOperate, + IdGeneratorManager idGeneratorManager, + @Qualifier("embeddedHistoryConfigInfoPersistServiceImpl") HistoryConfigInfoPersistService historyConfigInfoPersistService) { this.databaseOperate = databaseOperate; + this.idGeneratorManager = idGeneratorManager; + this.historyConfigInfoPersistService = historyConfigInfoPersistService; + idGeneratorManager.register(RESOURCE_CONFIG_HISTORY_GRAY_ID, RESOURCE_CONFIG_HISTORY_ID); this.dataSourceService = DynamicDataSource.getInstance().getDataSource(); Boolean isDataSourceLogEnable = EnvUtil.getProperty(CommonConstant.NACOS_PLUGIN_DATASOURCE_LOG, Boolean.class, false); @@ -117,7 +136,6 @@ private ConfigOperateResult getGrayOperateResult(String dataId, String group, St @Override public ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser) { - String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); @@ -125,28 +143,45 @@ public ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String gray configInfo.setTenant(tenantTmp); try { - String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); - ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_GRAY); - final String sql = configInfoGrayMapper.insert( - Arrays.asList("data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", "md5", "src_ip", - "src_user", "gmt_create", "gmt_modified")); - Timestamp time = new Timestamp(System.currentTimeMillis()); + long configGrayId = idGeneratorManager.nextId(RESOURCE_CONFIG_HISTORY_GRAY_ID); + long hisId = idGeneratorManager.nextId(RESOURCE_CONFIG_HISTORY_ID); - final Object[] args = new Object[] {configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp, grayRuleTmp, - appNameTmp, configInfo.getContent(), md5, srcIp, srcUser, time, time}; + addConfigInfoGrayAtomic(configGrayId, configInfo, grayNameTmp, grayRuleTmp, srcIp, srcUser); - EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, time); - EmbeddedStorageContextHolder.addSqlContext(sql, args); + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(hisId, configInfo, srcIp, srcUser, now, "I", + Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(grayNameTmp, grayRuleTmp, srcUser)); + EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, now); databaseOperate.blockUpdate(); - return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); } finally { EmbeddedStorageContextHolder.cleanAllContext(); } } + @Override + public void addConfigInfoGrayAtomic(long configGrayId, ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser) { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + + final String sql = configInfoGrayMapper.insert( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", "md5", "src_ip", + "src_user", "gmt_create", "gmt_modified")); + + Timestamp time = new Timestamp(System.currentTimeMillis()); + final Object[] args = new Object[] {configGrayId, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp, grayRuleTmp, + appNameTmp, configInfo.getContent(), md5, srcIp, srcUser, time, time}; + EmbeddedStorageContextHolder.addSqlContext(sql, args); + } + @Override public ConfigOperateResult insertOrUpdateGray(final ConfigInfo configInfo, final String grayName, final String grayRule, final String srcIp, final String srcUser) { @@ -173,11 +208,25 @@ public void removeConfigInfoGray(final String dataId, final String group, final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName; + ConfigAllInfo4Gray oldConfigAllInfo4Gray = findConfigAllInfo4Gray(dataId, group, tenantTmp, grayNameTmp); + if (oldConfigAllInfo4Gray == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + dataId, group, tenant); + } + } + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_GRAY); final String sql = configInfoGrayMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")); final Object[] args = new Object[] {dataId, group, tenantTmp, grayNameTmp}; + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo4Gray.getId(), + oldConfigAllInfo4Gray, srcIp, srcUser, now, + "D", Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(oldConfigAllInfo4Gray.getGrayName(), + oldConfigAllInfo4Gray.getGrayRule(), oldConfigAllInfo4Gray.getSrcUser())); + EmbeddedStorageContextUtils.onDeleteConfigGrayInfo(tenantTmp, group, dataId, grayNameTmp, srcIp); EmbeddedStorageContextHolder.addSqlContext(sql, args); try { @@ -198,8 +247,16 @@ public ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String g configInfo.setTenant(tenantTmp); try { - String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigAllInfo4Gray oldConfigAllInfo4Gray = findConfigAllInfo4Gray(configInfo.getDataId(), + configInfo.getGroup(), tenantTmp, grayNameTmp); + if (oldConfigAllInfo4Gray == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + } + } + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_GRAY); Timestamp time = new Timestamp(System.currentTimeMillis()); @@ -210,6 +267,10 @@ public ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String g final Object[] args = new Object[] {configInfo.getContent(), md5, srcIp, srcUser, time, appNameTmp, grayRuleTmp, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp}; + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo4Gray.getId(), oldConfigAllInfo4Gray, + srcIp, srcUser, now, "U", Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(oldConfigAllInfo4Gray.getGrayName(), oldConfigAllInfo4Gray.getGrayRule(), oldConfigAllInfo4Gray.getSrcUser())); + EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, time); EmbeddedStorageContextHolder.addSqlContext(sql, args); @@ -232,6 +293,15 @@ public ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, Strin configInfo.setTenant(tenantTmp); try { + final ConfigAllInfo4Gray oldConfigAllInfo4Gray = findConfigAllInfo4Gray(configInfo.getDataId(), + configInfo.getGroup(), tenantTmp, grayNameTmp); + if (oldConfigAllInfo4Gray == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + } + } + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_GRAY); @@ -254,6 +324,10 @@ public ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, Strin final MapperResult mapperResult = configInfoGrayMapper.updateConfigInfo4GrayCas(context); + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo4Gray.getId(), oldConfigAllInfo4Gray, + srcIp, srcUser, now, "U", Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(oldConfigAllInfo4Gray.getGrayName(), oldConfigAllInfo4Gray.getGrayRule(), oldConfigAllInfo4Gray.getSrcUser())); + EmbeddedStorageContextUtils.onModifyConfigGrayInfo(configInfo, grayNameTmp, grayRuleTmp, srcIp, time); EmbeddedStorageContextHolder.addSqlContext(mapperResult.getSql(), mapperResult.getParamList().toArray()); @@ -284,6 +358,20 @@ public ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final Stri CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); } + @Override + public ConfigAllInfo4Gray findConfigAllInfo4Gray(String dataId, String group, String tenant, String grayName) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + final String sql = configInfoGrayMapper.select( + Arrays.asList("id", "data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", + "src_ip", "src_user", "md5", "encrypted_data_key", "gmt_create", "gmt_modified"), Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")); + + return databaseOperate.queryOne(sql, new Object[] {dataId, group, tenantTmp, grayNameTmp}, + CONFIG_ALL_INFO_GRAY_ROW_MAPPER); + } + @Override public int configInfoGrayCount() { ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java index 58182e5dec8..a4060d9e989 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImpl.java @@ -35,6 +35,8 @@ import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.service.sql.EmbeddedStorageContextUtils; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; +import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.ParamUtils; import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; @@ -217,7 +219,9 @@ private ConfigOperateResult addConfigInfo(final String srcIp, final String srcUs configInfo.getTenant()); Timestamp now = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(hisId, configInfo, srcIp, srcUser, now, "I"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(hisId, configInfo, srcIp, srcUser, now, "I", + Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser)); + EmbeddedStorageContextUtils.onModifyConfigInfo(configInfo, srcIp, now); databaseOperate.blockUpdate(consumer); return getConfigInfoOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp); @@ -264,7 +268,7 @@ public long addConfigInfoAtomic(final long id, final String srcIp, final String configInfo.getEncryptedDataKey() == null ? StringUtils.EMPTY : configInfo.getEncryptedDataKey(); ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - + final String sql = configInfoMapper.insert( Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_ip", "src_user", "gmt_create@NOW()", "gmt_modified@NOW()", "c_desc", "c_use", "effect", @@ -398,15 +402,15 @@ public Map batchInsertOrUpdate(List configInfoLis public void removeConfigInfo(final String dataId, final String group, final String tenant, final String srcIp, final String srcUser) { final Timestamp time = new Timestamp(System.currentTimeMillis()); - ConfigInfo configInfo = findConfigInfo(dataId, group, tenant); - if (Objects.nonNull(configInfo)) { + ConfigAllInfo oldConfigAllInfo = findConfigAllInfo(dataId, group, tenant); + if (Objects.nonNull(oldConfigAllInfo)) { try { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; removeConfigInfoAtomic(dataId, group, tenantTmp, srcIp, srcUser); - removeTagByIdAtomic(configInfo.getId()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, - srcUser, time, "D"); + removeTagByIdAtomic(oldConfigAllInfo.getId()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo.getId(), oldConfigAllInfo, srcIp, + srcUser, time, "D", Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAllInfo(oldConfigAllInfo)); EmbeddedStorageContextUtils.onDeleteConfigInfo(tenantTmp, group, dataId, srcIp, time); @@ -421,7 +425,7 @@ public void removeConfigInfo(final String dataId, final String group, final Stri } @Override - public List removeConfigInfoByIds(final List ids, final String srcIp, final String srcUser) { + public List removeConfigInfoByIds(final List ids, final String srcIp, final String srcUser) { if (CollectionUtils.isEmpty(ids)) { return null; } @@ -429,23 +433,24 @@ public List removeConfigInfoByIds(final List ids, final String final Timestamp time = new Timestamp(System.currentTimeMillis()); try { String idsStr = StringUtils.join(ids, StringUtils.COMMA); - List configInfoList = findConfigInfosByIds(idsStr); - if (CollectionUtils.isNotEmpty(configInfoList)) { + List oldConfigAllInfoList = findAllConfigInfo4Export(null, null, null, null, ids); + if (CollectionUtils.isNotEmpty(oldConfigAllInfoList)) { removeConfigInfoByIdsAtomic(idsStr); - for (ConfigInfo configInfo : configInfoList) { - removeTagByIdAtomic(configInfo.getId()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, - srcUser, time, "D"); + for (ConfigAllInfo configAllInfo : oldConfigAllInfoList) { + removeTagByIdAtomic(configAllInfo.getId()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(configAllInfo.getId(), configAllInfo, + srcIp, srcUser, time, "D", Constants.FORMAL, + ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo)); } } - EmbeddedStorageContextUtils.onBatchDeleteConfigInfo(configInfoList); + EmbeddedStorageContextUtils.onBatchDeleteConfigInfo(oldConfigAllInfoList); boolean result = databaseOperate.update(EmbeddedStorageContextHolder.getCurrentSqlContext()); if (!result) { throw new NacosConfigException("Failed to config batch deletion"); } - return configInfoList; + return oldConfigAllInfoList; } finally { EmbeddedStorageContextHolder.cleanAllContext(); } @@ -494,15 +499,22 @@ public void removeConfigInfoByIdsAtomic(final String ids) { public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final String srcIp, final String srcUser, final Map configAdvanceInfo) { try { - ConfigInfo oldConfigInfo = findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), + ConfigAllInfo oldConfigAllInfo = findConfigAllInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + if (oldConfigAllInfo == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + } + return new ConfigOperateResult(false); + } final String tenantTmp = StringUtils.isBlank(configInfo.getTenant()) ? StringUtils.EMPTY : configInfo.getTenant(); - oldConfigInfo.setTenant(tenantTmp); + oldConfigAllInfo.setTenant(tenantTmp); - String appNameTmp = oldConfigInfo.getAppName(); + String appNameTmp = oldConfigAllInfo.getAppName(); // If the appName passed by the user is not empty, the appName of the user is persisted; // otherwise, the appName of db is used. Empty string is required to clear appName if (configInfo.getAppName() == null) { @@ -514,14 +526,14 @@ public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final S String configTags = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("config_tags"); if (configTags != null) { // Delete all tags and recreate them - removeTagByIdAtomic(oldConfigInfo.getId()); - addConfigTagsRelation(oldConfigInfo.getId(), configTags, configInfo.getDataId(), configInfo.getGroup(), + removeTagByIdAtomic(oldConfigAllInfo.getId()); + addConfigTagsRelation(oldConfigAllInfo.getId(), configTags, configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } Timestamp time = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, - srcUser, time, "U"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo.getId(), oldConfigAllInfo, srcIp, + srcUser, time, "U", Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAllInfo(oldConfigAllInfo)); EmbeddedStorageContextUtils.onModifyConfigInfo(configInfo, srcIp, time); databaseOperate.blockUpdate(); return getConfigInfoOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp); @@ -534,15 +546,21 @@ public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final S public ConfigOperateResult updateConfigInfoCas(final ConfigInfo configInfo, final String srcIp, final String srcUser, final Map configAdvanceInfo) { try { - ConfigInfo oldConfigInfo = findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), + ConfigAllInfo oldConfigAllInfo = findConfigAllInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); - + if (oldConfigAllInfo == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + } + return new ConfigOperateResult(false); + } final String tenantTmp = StringUtils.isBlank(configInfo.getTenant()) ? StringUtils.EMPTY : configInfo.getTenant(); - oldConfigInfo.setTenant(tenantTmp); + oldConfigAllInfo.setTenant(tenantTmp); - String appNameTmp = oldConfigInfo.getAppName(); + String appNameTmp = oldConfigAllInfo.getAppName(); // If the appName passed by the user is not empty, the appName of the user is persisted; // otherwise, the appName of db is used. Empty string is required to clear appName if (configInfo.getAppName() == null) { @@ -554,14 +572,14 @@ public ConfigOperateResult updateConfigInfoCas(final ConfigInfo configInfo, fina String configTags = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("config_tags"); if (configTags != null) { // Delete all tags and recreate them - removeTagByIdAtomic(oldConfigInfo.getId()); - addConfigTagsRelation(oldConfigInfo.getId(), configTags, configInfo.getDataId(), configInfo.getGroup(), + removeTagByIdAtomic(oldConfigAllInfo.getId()); + addConfigTagsRelation(oldConfigAllInfo.getId(), configTags, configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } - + Timestamp time = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, - srcUser, time, "U"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo.getId(), oldConfigAllInfo, srcIp, + srcUser, time, "U", Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAllInfo(oldConfigAllInfo)); EmbeddedStorageContextUtils.onModifyConfigInfo(configInfo, srcIp, time); boolean success = databaseOperate.blockUpdate(); if (success) { @@ -624,7 +642,7 @@ public void updateConfigInfoAtomic(final ConfigInfo configInfo, final String src final String schema = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("schema"); final String encryptedDataKey = configInfo.getEncryptedDataKey() == null ? StringUtils.EMPTY : configInfo.getEncryptedDataKey(); - + ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); final String sql = configInfoMapper.update( diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImpl.java index 4bfdf8ec65b..8be147fc0b0 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImpl.java @@ -24,6 +24,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnEmbeddedStorage; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; @@ -45,11 +46,11 @@ import org.springframework.stereotype.Service; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER; @@ -90,19 +91,20 @@ public PaginationHelper createPaginationHelper() { @Override public void insertConfigHistoryAtomic(long configHistoryId, ConfigInfo configInfo, String srcIp, String srcUser, - final Timestamp time, String ops) { + final Timestamp time, String ops, String publishType, String extInfo) { String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); final String md5Tmp = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + String publishTypeTmp = StringUtils.defaultEmptyIfBlank(publishType); String encryptedDataKey = StringUtils.defaultEmptyIfBlank(configInfo.getEncryptedDataKey()); HistoryConfigInfoMapper historyConfigInfoMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); final String sql = historyConfigInfoMapper.insert( Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_ip", - "src_user", "gmt_modified", "op_type", "encrypted_data_key")); + "src_user", "gmt_modified", "op_type", "publish_type", "ext_info", "encrypted_data_key")); final Object[] args = new Object[] {configHistoryId, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, - appNameTmp, configInfo.getContent(), md5Tmp, srcIp, srcUser, time, ops, encryptedDataKey}; + appNameTmp, configInfo.getContent(), md5Tmp, srcIp, srcUser, time, ops, publishTypeTmp, extInfo, encryptedDataKey}; EmbeddedStorageContextHolder.addSqlContext(sql, args); } @@ -121,17 +123,32 @@ public void removeConfigHistory(final Timestamp startTime, final int limitSize) @Override public List findDeletedConfig(final Timestamp startTime, long lastMaxId, - final int pageSize) { + final int pageSize, String publishType) { HistoryConfigInfoMapper historyConfigInfoMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); MapperContext context = new MapperContext(); context.putWhereParameter(FieldConstant.START_TIME, startTime); context.putWhereParameter(FieldConstant.PAGE_SIZE, pageSize); context.putWhereParameter(FieldConstant.LAST_MAX_ID, lastMaxId); + context.putWhereParameter(FieldConstant.PUBLISH_TYPE, publishType); MapperResult mapperResult = historyConfigInfoMapper.findDeletedConfig(context); - return databaseOperate.queryMany(mapperResult.getSql(), mapperResult.getParamList().toArray(), - CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + List configHistoryInfos = databaseOperate.queryMany(mapperResult.getSql(), + mapperResult.getParamList().toArray(), HISTORY_DETAIL_ROW_MAPPER); + + List configInfoStateWrappers = new ArrayList<>(); + for (ConfigHistoryInfo configHistoryInfo : configHistoryInfos) { + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setId(configHistoryInfo.getId()); + configInfoStateWrapper.setDataId(configHistoryInfo.getDataId()); + configInfoStateWrapper.setGroup(configHistoryInfo.getGroup()); + configInfoStateWrapper.setTenant(configHistoryInfo.getTenant()); + configInfoStateWrapper.setMd5(configHistoryInfo.getMd5()); + configInfoStateWrapper.setLastModified(configHistoryInfo.getLastModifiedTime().getTime()); + configInfoStateWrapper.setGrayName(ConfigExtInfoUtil.extractGrayName(configHistoryInfo.getExtInfo())); + configInfoStateWrappers.add(configInfoStateWrapper); + } + return configInfoStateWrappers; } @Override @@ -161,7 +178,7 @@ public ConfigHistoryInfo detailConfigHistory(Long nid) { dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); String sqlFetchRows = historyConfigInfoMapper.select( Arrays.asList("nid", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_user", - "src_ip", "op_type", "gmt_create", "gmt_modified", "encrypted_data_key"), + "src_ip", "op_type", "publish_type", "ext_info", "gmt_create", "gmt_modified", "encrypted_data_key"), Collections.singletonList("nid")); return databaseOperate.queryOne(sqlFetchRows, new Object[] {nid}, HISTORY_DETAIL_ROW_MAPPER); } diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java index 0a3caf58445..ae7f9874827 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImpl.java @@ -19,11 +19,14 @@ import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigAllInfo4Gray; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import com.alibaba.nacos.persistence.datasource.DataSourceService; @@ -39,12 +42,15 @@ import com.alibaba.nacos.plugin.datasource.model.MapperContext; import com.alibaba.nacos.plugin.datasource.model.MapperResult; import com.alibaba.nacos.sys.env.EnvUtil; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Conditional; import org.springframework.dao.DataAccessException; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.CannotGetJdbcConnectionException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import java.sql.Timestamp; @@ -52,6 +58,7 @@ import java.util.Collections; import java.util.List; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_GRAY_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; @@ -74,7 +81,11 @@ public class ExternalConfigInfoGrayPersistServiceImpl implements ConfigInfoGrayP private MapperManager mapperManager; - public ExternalConfigInfoGrayPersistServiceImpl() { + private HistoryConfigInfoPersistService historyConfigInfoPersistService; + + public ExternalConfigInfoGrayPersistServiceImpl( + @Qualifier("externalHistoryConfigInfoPersistServiceImpl") HistoryConfigInfoPersistService historyConfigInfoPersistService) { + this.historyConfigInfoPersistService = historyConfigInfoPersistService; this.dataSourceService = DynamicDataSource.getInstance().getDataSource(); this.jt = dataSourceService.getJdbcTemplate(); this.tjt = dataSourceService.getTransactionTemplate(); @@ -119,25 +130,39 @@ private ConfigOperateResult getGrayOperateResult(String dataId, String group, St @Override public ConfigOperateResult addConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser) { + return tjt.execute(status -> { + String tenantTmp = StringUtils.isBlank(configInfo.getTenant()) ? StringUtils.EMPTY : configInfo.getTenant().trim(); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + try { + addConfigInfoGrayAtomic(-1, configInfo, grayNameTmp, grayRuleTmp, srcIp, srcUser); + + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(0, configInfo, srcIp, srcUser, now, "I", + Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(grayNameTmp, grayRuleTmp, srcUser)); + + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + } catch (Exception e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + }); + } + + @Override + public void addConfigInfoGrayAtomic(long configGrayId, ConfigInfo configInfo, String grayName, String grayRule, + String srcIp, String srcUser) { String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); - String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); - String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); - try { - ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_GRAY); - jt.update(configInfoGrayMapper.insert( - Arrays.asList("data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", - "encrypted_data_key", "md5", "src_ip", "src_user", "gmt_create@NOW()", "gmt_modified@NOW()")), - configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp, grayRuleTmp, appNameTmp, - configInfo.getContent(), configInfo.getEncryptedDataKey(), md5, srcIp, srcUser); - return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); - - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } + + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + jt.update(configInfoGrayMapper.insert( + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", "content", + "encrypted_data_key", "md5", "src_ip", "src_user", "gmt_create@NOW()", "gmt_modified@NOW()")), + configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayName, grayRule, appNameTmp, + configInfo.getContent(), configInfo.getEncryptedDataKey(), md5, srcIp, srcUser); } @Override @@ -165,78 +190,153 @@ public ConfigOperateResult insertOrUpdateGrayCas(final ConfigInfo configInfo, fi @Override public void removeConfigInfoGray(final String dataId, final String group, final String tenant, final String grayName, final String srcIp, final String srcUser) { - String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; - String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName; - try { - ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_GRAY); - jt.update(configInfoGrayMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), - dataId, group, tenantTmp, grayNameTmp); - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } + tjt.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName; + try { + ConfigAllInfo4Gray oldConfigAllInfo4Gray = findConfigAllInfo4Gray(dataId, group, + tenantTmp, grayNameTmp); + if (oldConfigAllInfo4Gray == null) { + if (LogUtil.FATAL_LOG.isWarnEnabled()) { + LogUtil.FATAL_LOG.warn("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + dataId, group, tenant); + } + } + + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper( + dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_GRAY); + jt.update( + configInfoGrayMapper.delete(Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + dataId, group, tenantTmp, grayNameTmp); + + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo4Gray.getId(), + oldConfigAllInfo4Gray, srcIp, srcUser, now, + "D", Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(oldConfigAllInfo4Gray.getGrayName(), + oldConfigAllInfo4Gray.getGrayRule(), oldConfigAllInfo4Gray.getSrcUser())); + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + } + }); } @Override public ConfigOperateResult updateConfigInfo4Gray(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser) { - String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); - String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); - String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); - String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); - try { - String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); - ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), - TableConstant.CONFIG_INFO_GRAY); - jt.update(configInfoGrayMapper.update( - Arrays.asList("content", "encrypted_data_key", "md5", "src_ip", "src_user", "gmt_modified@NOW()", - "app_name", "gray_rule"), Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), - configInfo.getContent(), configInfo.getEncryptedDataKey(), md5, srcIp, srcUser, appNameTmp, - grayRuleTmp, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); - return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); - - } catch (CannotGetJdbcConnectionException e) { - LogUtil.FATAL_LOG.error("[db-error] " + e, e); - throw e; - } + return tjt.execute(status -> { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + try { + ConfigAllInfo4Gray oldConfigAllInfo4Gray = findConfigAllInfo4Gray(configInfo.getDataId(), configInfo.getGroup(), + tenantTmp, grayNameTmp); + if (oldConfigAllInfo4Gray == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + } + } + + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + jt.update(configInfoGrayMapper.update( + Arrays.asList("content", "encrypted_data_key", "md5", "src_ip", "src_user", "gmt_modified@NOW()", + "app_name", "gray_rule"), Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + configInfo.getContent(), configInfo.getEncryptedDataKey(), md5, srcIp, srcUser, appNameTmp, + grayRuleTmp, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo4Gray.getId(), + oldConfigAllInfo4Gray, srcIp, srcUser, now, + "U", Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(oldConfigAllInfo4Gray.getGrayName(), + oldConfigAllInfo4Gray.getGrayRule(), oldConfigAllInfo4Gray.getSrcUser())); + + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + }); } @Override public ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, String grayName, String grayRule, String srcIp, String srcUser) { - String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); - String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + return tjt.execute(status -> { + String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); + String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); + String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); + String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); + try { + String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); + ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), + TableConstant.CONFIG_INFO_GRAY); + Timestamp time = new Timestamp(System.currentTimeMillis()); + + MapperContext context = new MapperContext(); + context.putUpdateParameter(FieldConstant.CONTENT, configInfo.getContent()); + context.putUpdateParameter(FieldConstant.MD5, md5); + context.putUpdateParameter(FieldConstant.SRC_IP, srcIp); + context.putUpdateParameter(FieldConstant.SRC_USER, srcUser); + context.putUpdateParameter(FieldConstant.APP_NAME, appNameTmp); + + context.putWhereParameter(FieldConstant.DATA_ID, configInfo.getDataId()); + context.putWhereParameter(FieldConstant.GROUP_ID, configInfo.getGroup()); + context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); + context.putWhereParameter(FieldConstant.GRAY_NAME, grayNameTmp); + context.putWhereParameter(FieldConstant.GRAY_RULE, grayRuleTmp); + context.putWhereParameter(FieldConstant.MD5, configInfo.getMd5()); + + final MapperResult mapperResult = configInfoGrayMapper.updateConfigInfo4GrayCas(context); + boolean success = jt.update(mapperResult.getSql(), mapperResult.getParamList().toArray()) > 0; + + ConfigAllInfo4Gray oldConfigAllInfo4Gray = findConfigAllInfo4Gray(configInfo.getDataId(), configInfo.getGroup(), + tenantTmp, grayNameTmp); + if (oldConfigAllInfo4Gray == null) { + if (LogUtil.FATAL_LOG.isErrorEnabled()) { + LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", + configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); + } + } + + Timestamp now = new Timestamp(System.currentTimeMillis()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo4Gray.getId(), oldConfigAllInfo4Gray, srcIp, srcUser, now, + "U", Constants.GRAY, ConfigExtInfoUtil.getExtraInfoFromGrayInfo(oldConfigAllInfo4Gray.getGrayName(), + oldConfigAllInfo4Gray.getGrayRule(), oldConfigAllInfo4Gray.getSrcUser())); + + if (success) { + return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); + } else { + return new ConfigOperateResult(false); + } + } catch (CannotGetJdbcConnectionException e) { + LogUtil.FATAL_LOG.error("[db-error] " + e, e); + throw e; + } + }); + } + + @Override + public ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String group, final String tenant, + final String grayName) { + String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); - String grayRuleTmp = StringUtils.isBlank(grayRule) ? StringUtils.EMPTY : grayRule.trim(); try { - String md5 = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_GRAY); - Timestamp time = new Timestamp(System.currentTimeMillis()); - - MapperContext context = new MapperContext(); - context.putUpdateParameter(FieldConstant.CONTENT, configInfo.getContent()); - context.putUpdateParameter(FieldConstant.MD5, md5); - context.putUpdateParameter(FieldConstant.SRC_IP, srcIp); - context.putUpdateParameter(FieldConstant.SRC_USER, srcUser); - context.putUpdateParameter(FieldConstant.APP_NAME, appNameTmp); - - context.putWhereParameter(FieldConstant.DATA_ID, configInfo.getDataId()); - context.putWhereParameter(FieldConstant.GROUP_ID, configInfo.getGroup()); - context.putWhereParameter(FieldConstant.TENANT_ID, tenantTmp); - context.putWhereParameter(FieldConstant.GRAY_NAME, grayNameTmp); - context.putWhereParameter(FieldConstant.GRAY_RULE, grayRuleTmp); - context.putWhereParameter(FieldConstant.MD5, configInfo.getMd5()); - - final MapperResult mapperResult = configInfoGrayMapper.updateConfigInfo4GrayCas(context); - - boolean success = jt.update(mapperResult.getSql(), mapperResult.getParamList().toArray()) > 0; - if (success) { - return getGrayOperateResult(configInfo.getDataId(), configInfo.getGroup(), tenantTmp, grayNameTmp); - } else { - return new ConfigOperateResult(false); - } + return this.jt.queryForObject(configInfoGrayMapper.select( + Arrays.asList("id", "md5", "data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", + "content", "encrypted_data_key", "gmt_modified"), + Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), + new Object[] {dataId, group, tenantTmp, grayNameTmp}, CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. + return null; } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; @@ -244,18 +344,17 @@ public ConfigOperateResult updateConfigInfo4GrayCas(ConfigInfo configInfo, Strin } @Override - public ConfigInfoGrayWrapper findConfigInfo4Gray(final String dataId, final String group, final String tenant, - final String grayName) { + public ConfigAllInfo4Gray findConfigAllInfo4Gray(String dataId, String group, String tenant, String grayName) { String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant; String grayNameTmp = StringUtils.isBlank(grayName) ? StringUtils.EMPTY : grayName.trim(); try { ConfigInfoGrayMapper configInfoGrayMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO_GRAY); return this.jt.queryForObject(configInfoGrayMapper.select( - Arrays.asList("id", "md5", "data_id", "group_id", "tenant_id", "gray_name", "gray_rule", "app_name", - "content", "encrypted_data_key", "gmt_modified"), + Arrays.asList("id", "md5", "data_id", "group_id", "src_user", "src_ip", "tenant_id", "gray_name", "gray_rule", "app_name", + "content", "encrypted_data_key", "gmt_create", "gmt_modified"), Arrays.asList("data_id", "group_id", "tenant_id", "gray_name")), - new Object[] {dataId, group, tenantTmp, grayNameTmp}, CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER); + new Object[] {dataId, group, tenantTmp, grayNameTmp}, CONFIG_ALL_INFO_GRAY_ROW_MAPPER); } catch (EmptyResultDataAccessException e) { // Indicates that the data does not exist, returns null. return null; } catch (CannotGetJdbcConnectionException e) { diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java index 912b13e080c..a4949421e5e 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImpl.java @@ -32,6 +32,7 @@ import com.alibaba.nacos.config.server.service.repository.ConfigInfoPersistService; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.config.server.utils.ParamUtils; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; @@ -147,7 +148,8 @@ public ConfigOperateResult addConfigInfo(final String srcIp, final String srcUse configInfo.getTenant()); Timestamp now = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(0, configInfo, srcIp, srcUser, now, "I"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(0, configInfo, srcIp, srcUser, now, "I", + Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser)); ConfigInfoStateWrapper configInfoCurrent = this.findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); if (configInfoCurrent == null) { @@ -394,12 +396,12 @@ public void removeConfigInfo(final String dataId, final String group, final Stri @Override public Boolean doInTransaction(TransactionStatus status) { try { - ConfigInfo configInfo = findConfigInfo(dataId, group, tenant); - if (configInfo != null) { + ConfigAllInfo oldConfigAllInfo = findConfigAllInfo(dataId, group, tenant); + if (oldConfigAllInfo != null) { removeConfigInfoAtomic(dataId, group, tenant, srcIp, srcUser); - removeTagByIdAtomic(configInfo.getId()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(configInfo.getId(), configInfo, srcIp, - srcUser, time, "D"); + removeTagByIdAtomic(oldConfigAllInfo.getId()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo.getId(), oldConfigAllInfo, + srcIp, srcUser, time, "D", Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAllInfo(oldConfigAllInfo)); } } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); @@ -411,28 +413,29 @@ public Boolean doInTransaction(TransactionStatus status) { } @Override - public List removeConfigInfoByIds(final List ids, final String srcIp, final String srcUser) { + public List removeConfigInfoByIds(final List ids, final String srcIp, final String srcUser) { if (CollectionUtils.isEmpty(ids)) { return null; } ids.removeAll(Collections.singleton(null)); - return tjt.execute(new TransactionCallback>() { + return tjt.execute(new TransactionCallback>() { final Timestamp time = new Timestamp(System.currentTimeMillis()); @Override - public List doInTransaction(TransactionStatus status) { + public List doInTransaction(TransactionStatus status) { try { String idsStr = StringUtils.join(ids, StringUtils.COMMA); - List configInfoList = findConfigInfosByIds(idsStr); - if (!CollectionUtils.isEmpty(configInfoList)) { + List oldConfigAllInfoList = findAllConfigInfo4Export(null, null, null, null, ids); + if (!CollectionUtils.isEmpty(oldConfigAllInfoList)) { removeConfigInfoByIdsAtomic(idsStr); - for (ConfigInfo configInfo : configInfoList) { - removeTagByIdAtomic(configInfo.getId()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(configInfo.getId(), configInfo, - srcIp, srcUser, time, "D"); + for (ConfigAllInfo configAllInfo : oldConfigAllInfoList) { + removeTagByIdAtomic(configAllInfo.getId()); + historyConfigInfoPersistService.insertConfigHistoryAtomic(configAllInfo.getId(), + configAllInfo, srcIp, srcUser, time, "D", Constants.FORMAL, + ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo)); } } - return configInfoList; + return oldConfigAllInfoList; } catch (CannotGetJdbcConnectionException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; @@ -496,9 +499,9 @@ public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final S final Map configAdvanceInfo) { return tjt.execute(status -> { try { - ConfigInfo oldConfigInfo = findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), + ConfigAllInfo oldConfigAllInfo = findConfigAllInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); - if (oldConfigInfo == null) { + if (oldConfigAllInfo == null) { if (LogUtil.FATAL_LOG.isErrorEnabled()) { LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); @@ -506,7 +509,7 @@ public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final S return new ConfigOperateResult(false); } - String appNameTmp = oldConfigInfo.getAppName(); + String appNameTmp = oldConfigAllInfo.getAppName(); /* If the appName passed by the user is not empty, use the persistent user's appName, otherwise use db; when emptying appName, you need to pass an empty string @@ -518,14 +521,14 @@ public ConfigOperateResult updateConfigInfo(final ConfigInfo configInfo, final S String configTags = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("config_tags"); if (configTags != null) { // delete all tags and then recreate - removeTagByIdAtomic(oldConfigInfo.getId()); - addConfigTagsRelation(oldConfigInfo.getId(), configTags, configInfo.getDataId(), + removeTagByIdAtomic(oldConfigAllInfo.getId()); + addConfigTagsRelation(oldConfigAllInfo.getId(), configTags, configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } - + Timestamp now = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, - srcUser, now, "U"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigAllInfo.getId(), oldConfigAllInfo, srcIp, srcUser, + now, "U", Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAllInfo(oldConfigAllInfo)); return getConfigInfoOperateResult(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } catch (CannotGetJdbcConnectionException e) { @@ -549,16 +552,16 @@ public ConfigOperateResult updateConfigInfoCas(final ConfigInfo configInfo, fina final String srcUser, final Map configAdvanceInfo) { return tjt.execute(status -> { try { - ConfigInfo oldConfigInfo = findConfigInfo(configInfo.getDataId(), configInfo.getGroup(), + ConfigAllInfo oldAllConfigInfo = findConfigAllInfo(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); - if (oldConfigInfo == null) { + if (oldAllConfigInfo == null) { if (LogUtil.FATAL_LOG.isErrorEnabled()) { LogUtil.FATAL_LOG.error("expected config info[dataid:{}, group:{}, tenent:{}] but not found.", configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } return new ConfigOperateResult(false); } - String appNameTmp = oldConfigInfo.getAppName(); + String appNameTmp = oldAllConfigInfo.getAppName(); /* If the appName passed by the user is not empty, use the persistent user's appName, otherwise use db; when emptying appName, you need to pass an empty string @@ -573,14 +576,14 @@ public ConfigOperateResult updateConfigInfoCas(final ConfigInfo configInfo, fina String configTags = configAdvanceInfo == null ? null : (String) configAdvanceInfo.get("config_tags"); if (configTags != null) { // delete all tags and then recreate - removeTagByIdAtomic(oldConfigInfo.getId()); - addConfigTagsRelation(oldConfigInfo.getId(), configTags, configInfo.getDataId(), + removeTagByIdAtomic(oldAllConfigInfo.getId()); + addConfigTagsRelation(oldAllConfigInfo.getId(), configTags, configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); } Timestamp now = new Timestamp(System.currentTimeMillis()); - historyConfigInfoPersistService.insertConfigHistoryAtomic(oldConfigInfo.getId(), oldConfigInfo, srcIp, - srcUser, now, "U"); + historyConfigInfoPersistService.insertConfigHistoryAtomic(oldAllConfigInfo.getId(), oldAllConfigInfo, srcIp, srcUser, now, + "U", Constants.FORMAL, ConfigExtInfoUtil.getExtraInfoFromAllInfo(oldAllConfigInfo)); ConfigInfoStateWrapper configInfoLast = this.findConfigInfoState(configInfo.getDataId(), configInfo.getGroup(), configInfo.getTenant()); if (configInfoLast == null) { @@ -609,7 +612,7 @@ private int updateConfigInfoAtomicCas(final ConfigInfo configInfo, final String try { ConfigInfoMapper configInfoMapper = mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_INFO); - + MapperContext context = new MapperContext(); context.putUpdateParameter(FieldConstant.CONTENT, configInfo.getContent()); context.putUpdateParameter(FieldConstant.MD5, md5Tmp); diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java index eeec61d6130..00df35b8667 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImpl.java @@ -23,6 +23,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.config.server.utils.LogUtil; import com.alibaba.nacos.persistence.configuration.condition.ConditionOnExternalStorage; import com.alibaba.nacos.persistence.datasource.DataSourceService; @@ -46,11 +47,11 @@ import org.springframework.transaction.support.TransactionTemplate; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER; @@ -88,20 +89,21 @@ public PaginationHelper createPaginationHelper() { @Override public void insertConfigHistoryAtomic(long id, ConfigInfo configInfo, String srcIp, String srcUser, - final Timestamp time, String ops) { + final Timestamp time, String ops, String publishType, String extInfo) { String appNameTmp = StringUtils.defaultEmptyIfBlank(configInfo.getAppName()); String tenantTmp = StringUtils.defaultEmptyIfBlank(configInfo.getTenant()); final String md5Tmp = MD5Utils.md5Hex(configInfo.getContent(), Constants.ENCODE); String encryptedDataKey = StringUtils.defaultEmptyIfBlank(configInfo.getEncryptedDataKey()); + String publishTypeTmp = StringUtils.defaultEmptyIfBlank(publishType); try { HistoryConfigInfoMapper historyConfigInfoMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); jt.update(historyConfigInfoMapper.insert( Arrays.asList("id", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_ip", - "src_user", "gmt_modified", "op_type", "encrypted_data_key")), id, configInfo.getDataId(), - configInfo.getGroup(), tenantTmp, appNameTmp, configInfo.getContent(), md5Tmp, srcIp, srcUser, time, - ops, encryptedDataKey); + "src_user", "gmt_modified", "op_type", "publish_type", "ext_info", "encrypted_data_key")), + id, configInfo.getDataId(), configInfo.getGroup(), tenantTmp, appNameTmp, configInfo.getContent(), + md5Tmp, srcIp, srcUser, time, ops, publishTypeTmp, extInfo, encryptedDataKey); } catch (DataAccessException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; @@ -121,7 +123,8 @@ public void removeConfigHistory(final Timestamp startTime, final int limitSize) } @Override - public List findDeletedConfig(final Timestamp startTime, long startId, int pageSize) { + public List findDeletedConfig(final Timestamp startTime, long startId, int pageSize, + String publishType) { try { HistoryConfigInfoMapper historyConfigInfoMapper = mapperManager.findMapper( dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); @@ -129,10 +132,25 @@ public List findDeletedConfig(final Timestamp startTime, context.putWhereParameter(FieldConstant.START_TIME, startTime); context.putWhereParameter(FieldConstant.PAGE_SIZE, pageSize); context.putWhereParameter(FieldConstant.LAST_MAX_ID, startId); + context.putWhereParameter(FieldConstant.PUBLISH_TYPE, publishType); MapperResult mapperResult = historyConfigInfoMapper.findDeletedConfig(context); - return jt.query(mapperResult.getSql(), mapperResult.getParamList().toArray(), - CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER); + List configHistoryInfos = jt.query(mapperResult.getSql(), mapperResult.getParamList().toArray(), + HISTORY_DETAIL_ROW_MAPPER); + + List configInfoStateWrappers = new ArrayList<>(); + for (ConfigHistoryInfo configHistoryInfo : configHistoryInfos) { + ConfigInfoStateWrapper configInfoStateWrapper = new ConfigInfoStateWrapper(); + configInfoStateWrapper.setId(configHistoryInfo.getId()); + configInfoStateWrapper.setDataId(configHistoryInfo.getDataId()); + configInfoStateWrapper.setGroup(configHistoryInfo.getGroup()); + configInfoStateWrapper.setTenant(configHistoryInfo.getTenant()); + configInfoStateWrapper.setMd5(configHistoryInfo.getMd5()); + configInfoStateWrapper.setLastModified(configHistoryInfo.getLastModifiedTime().getTime()); + configInfoStateWrapper.setGrayName(ConfigExtInfoUtil.extractGrayName(configHistoryInfo.getExtInfo())); + configInfoStateWrappers.add(configInfoStateWrapper); + } + return configInfoStateWrappers; } catch (DataAccessException e) { LogUtil.FATAL_LOG.error("[db-error] " + e, e); throw e; @@ -174,7 +192,7 @@ public ConfigHistoryInfo detailConfigHistory(Long nid) { dataSourceService.getDataSourceType(), TableConstant.HIS_CONFIG_INFO); String sqlFetchRows = historyConfigInfoMapper.select( Arrays.asList("nid", "data_id", "group_id", "tenant_id", "app_name", "content", "md5", "src_user", - "src_ip", "op_type", "gmt_create", "gmt_modified", "encrypted_data_key"), + "src_ip", "op_type", "gmt_create", "gmt_modified", "publish_type", "ext_info", "encrypted_data_key"), Collections.singletonList("nid")); try { ConfigHistoryInfo historyInfo = jt.queryForObject(sqlFetchRows, new Object[] {nid}, diff --git a/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java b/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java index 1190a91ef80..ecd06f734f7 100644 --- a/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java +++ b/config/src/main/java/com/alibaba/nacos/config/server/service/sql/EmbeddedStorageContextUtils.java @@ -19,6 +19,7 @@ import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.StringUtils; import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigAllInfo; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.event.ConfigDumpEvent; import com.alibaba.nacos.persistence.repository.embedded.EmbeddedStorageContextHolder; @@ -151,12 +152,12 @@ public static void onDeleteConfigInfo(String namespaceId, String group, String d * In the case of the in-cluster storage mode, the logic of horizontal notification is implemented asynchronously * via the raft state machine, along with the information. * - * @param configInfos {@link ConfigInfo} list + * @param configInfos {@link ConfigAllInfo} list */ - public static void onBatchDeleteConfigInfo(List configInfos) { + public static void onBatchDeleteConfigInfo(List configInfos) { if (!EnvUtil.getStandaloneMode()) { List events = new ArrayList<>(); - for (ConfigInfo configInfo : configInfos) { + for (ConfigAllInfo configInfo : configInfos) { String namespaceId = StringUtils.isBlank(configInfo.getTenant()) ? StringUtils.EMPTY : configInfo.getTenant(); ConfigDumpEvent event = ConfigDumpEvent.builder().remove(true).namespaceId(namespaceId) diff --git a/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExtInfoUtil.java b/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExtInfoUtil.java new file mode 100644 index 00000000000..f9627c57cf5 --- /dev/null +++ b/config/src/main/java/com/alibaba/nacos/config/server/utils/ConfigExtInfoUtil.java @@ -0,0 +1,186 @@ +/* + * Copyright 1999-$toady.year Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.nacos.config.server.utils; + +import com.alibaba.nacos.common.utils.StringUtils; +import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigAllInfo; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Map; + +/** + * Extra info util. + * + * @author Nacos + */ +public class ConfigExtInfoUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigExtInfoUtil.class); + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private static final Map EXTRA_INFO_KEYS_MAPPING = new HashMap<>(); + + static { + EXTRA_INFO_KEYS_MAPPING.put("type", "type"); + EXTRA_INFO_KEYS_MAPPING.put("config_tags", "config_tags"); + EXTRA_INFO_KEYS_MAPPING.put("src_user", "src_user"); + EXTRA_INFO_KEYS_MAPPING.put("desc", "c_desc"); + EXTRA_INFO_KEYS_MAPPING.put("use", "c_use"); + EXTRA_INFO_KEYS_MAPPING.put("effect", "effect"); + EXTRA_INFO_KEYS_MAPPING.put("schema", "c_schema"); + } + + private ConfigExtInfoUtil() { + } + + /** + * Extract the extInfo from advance config info. + */ + public static String getExtraInfoFromAdvanceInfoMap(Map advanceConfigInfoMap, String srcUser) { + try { + if (advanceConfigInfoMap == null || advanceConfigInfoMap.isEmpty()) { + return null; + } + + ObjectNode node = OBJECT_MAPPER.createObjectNode(); + + if (StringUtils.isNotBlank(srcUser)) { + node.put("src_user", srcUser); + } + + for (Map.Entry entry : EXTRA_INFO_KEYS_MAPPING.entrySet()) { + String key = entry.getKey(); + String mappedKey = entry.getValue(); + Object advanceConfigInfoValue = advanceConfigInfoMap.get(key); + if (advanceConfigInfoValue instanceof String && StringUtils.isNotBlank((String) advanceConfigInfoValue)) { + node.put(mappedKey, ((String) advanceConfigInfoValue).trim()); + } + } + + return OBJECT_MAPPER.writeValueAsString(node); + } catch (Exception ex) { + LOGGER.error("Failed to get extra info from advance info map", ex); + return null; + } + } + + /** + * Extract the extInfo from all config info. + */ + public static String getExtraInfoFromAllInfo(ConfigAllInfo configAllInfo) { + ObjectNode node = OBJECT_MAPPER.createObjectNode(); + + if (StringUtils.isNotBlank(configAllInfo.getType())) { + node.put("type", configAllInfo.getType()); + } + if (StringUtils.isNotBlank(configAllInfo.getConfigTags())) { + node.put("config_tags", configAllInfo.getConfigTags()); + } + if (StringUtils.isNotBlank(configAllInfo.getEffect())) { + node.put("effect", configAllInfo.getEffect()); + } + if (StringUtils.isNotBlank(configAllInfo.getCreateUser())) { + node.put("src_user", configAllInfo.getCreateUser()); + } + if (StringUtils.isNotBlank(configAllInfo.getDesc())) { + node.put("c_desc", configAllInfo.getDesc()); + } + if (StringUtils.isNotBlank(configAllInfo.getUse())) { + node.put("c_use", configAllInfo.getUse()); + } + if (StringUtils.isNotBlank(configAllInfo.getSchema())) { + node.put("c_schema", configAllInfo.getSchema()); + } + + try { + return OBJECT_MAPPER.writeValueAsString(node); + } catch (Exception ex) { + LOGGER.error("Failed to get extra info from all config info", ex); + return null; + } + } + + /** + * Extract the extInfo from gray config info. + */ + public static String getExtraInfoFromGrayInfo(String grayNameTmp, String grayRuleTmp, String oldSrcUser) { + ObjectNode node = OBJECT_MAPPER.createObjectNode(); + ObjectNode grayRuleNode = OBJECT_MAPPER.createObjectNode(); + + if (StringUtils.isNotBlank(grayNameTmp)) { + node.put("gray_name", grayNameTmp); + } + + if (StringUtils.isNotBlank(oldSrcUser)) { + node.put("src_user", oldSrcUser); + } + + if (StringUtils.isNotBlank(grayRuleTmp)) { + try { + JsonNode parsedGrayRuleNode = OBJECT_MAPPER.readTree(grayRuleTmp); + if (parsedGrayRuleNode.has(Constants.GRAY_RULE_TYPE)) { + grayRuleNode.put(Constants.GRAY_RULE_TYPE, parsedGrayRuleNode.get(Constants.GRAY_RULE_TYPE).asText()); + } + if (parsedGrayRuleNode.has(Constants.GRAY_RULE_EXPR)) { + grayRuleNode.put(Constants.GRAY_RULE_EXPR, parsedGrayRuleNode.get(Constants.GRAY_RULE_EXPR).asText()); + } + if (parsedGrayRuleNode.has(Constants.GRAY_RULE_VERSION)) { + grayRuleNode.put(Constants.GRAY_RULE_VERSION, parsedGrayRuleNode.get(Constants.GRAY_RULE_VERSION).asText()); + } + if (parsedGrayRuleNode.has(Constants.GRAY_RULE_PRIORITY)) { + grayRuleNode.put(Constants.GRAY_RULE_PRIORITY, parsedGrayRuleNode.get(Constants.GRAY_RULE_PRIORITY).asText()); + } + node.set("gray_rule", grayRuleNode); + } catch (Exception ex) { + LOGGER.error("Failed to parse gray rule as json", ex); + return null; + } + } + + node.put("type", "json"); + + try { + return OBJECT_MAPPER.writeValueAsString(node); + } catch (Exception ex) { + LOGGER.error("Failed to serialize extra info from gray info", ex); + return null; + } + } + + /** + * Extract grayName from extInfo. + */ + public static String extractGrayName(String extraInfo) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + Map dataMap = objectMapper.readValue(extraInfo, new TypeReference>() { }); + return dataMap.get("gray_name"); + } catch (Exception e) { + LogUtil.DEFAULT_LOG.error("Error extracting gray_name from extraInfo", e); + return null; + } + } + +} \ No newline at end of file diff --git a/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigControllerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigControllerTest.java index 0d928bb57bf..ff30cf0d250 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigControllerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/controller/ConfigControllerTest.java @@ -183,11 +183,15 @@ void testDeleteConfig() throws Exception { @Test void testDeleteConfigs() throws Exception { - List resultInfos = new ArrayList<>(); + final List resultInfos = new ArrayList<>(); + ConfigAllInfo configAllInfo = new ConfigAllInfo(); String dataId = "dataId1123"; String group = "group34567"; String tenant = "tenant45678"; - resultInfos.add(new ConfigInfo(dataId, group, tenant)); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + resultInfos.add(configAllInfo); Mockito.when(configInfoPersistService.removeConfigInfoByIds(eq(Arrays.asList(1L, 2L)), anyString(), eq(null))) .thenReturn(resultInfos); AtomicReference reference = new AtomicReference<>(); diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java index 77f2944d07d..614d655c90e 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeConfigWorkerTest.java @@ -120,7 +120,7 @@ void after() throws IllegalAccessException { void testDumpChangeIfOff() { PropertyUtil.setDumpChangeOn(false); dumpChangeConfigWorker.run(); - Mockito.verify(historyConfigInfoPersistService, times(0)).findDeletedConfig(any(), anyLong(), anyInt()); + Mockito.verify(historyConfigInfoPersistService, times(0)).findDeletedConfig(any(), anyLong(), anyInt(), any()); } @Test @@ -140,7 +140,7 @@ void testDumpChangeOfDeleteConfigs() { assertEquals("encrykey" + 1, ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1)).getConfigCache() .getEncryptedDataKey()); - Mockito.when(historyConfigInfoPersistService.findDeletedConfig(eq(startTime), eq(0L), eq(3))).thenReturn(firstPageDeleted); + Mockito.when(historyConfigInfoPersistService.findDeletedConfig(eq(startTime), eq(0L), eq(3), eq("formal"))).thenReturn(firstPageDeleted); //mock delete config query is null Mockito.when(configInfoPersistService.findConfigInfoState(eq(dataIdPrefix + 1), eq("group" + 1), eq("tenant" + 1))) .thenReturn(null); @@ -149,7 +149,7 @@ void testDumpChangeOfDeleteConfigs() { dumpChangeConfigWorker.run(); //expect delete page return pagesize and will select second page - Mockito.verify(historyConfigInfoPersistService, times(1)).findDeletedConfig(eq(startTime), eq(3L), eq(3)); + Mockito.verify(historyConfigInfoPersistService, times(1)).findDeletedConfig(eq(startTime), eq(3L), eq(3), eq("formal")); //expect cache to be cleared. assertNull(ConfigCacheService.getContentCache(GroupKey.getKeyTenant(dataIdPrefix + 1, "group" + 1, "tenant" + 1))); } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java index ac8d0d7f9bb..f1f825241e5 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/dump/DumpChangeGrayConfigWorkerTest.java @@ -19,6 +19,7 @@ import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.service.ConfigCacheService; import com.alibaba.nacos.config.server.service.repository.ConfigInfoGrayPersistService; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.utils.ConfigExecutor; import com.alibaba.nacos.config.server.utils.GroupKey; import com.alibaba.nacos.config.server.utils.PropertyUtil; @@ -50,6 +51,9 @@ public class DumpChangeGrayConfigWorkerTest { @Mock ConfigInfoGrayPersistService configInfoGrayPersistService; + @Mock + HistoryConfigInfoPersistService historyConfigInfoPersistService; + static MockedStatic envUtilMockedStatic; static MockedStatic configCacheServiceMockedStatic; @@ -76,7 +80,7 @@ public void setUp() { envUtilMockedStatic.when(() -> EnvUtil.getAvailableProcessors(anyInt())).thenReturn(2); dumpGrayConfigWorker = new DumpChangeGrayConfigWorker(configInfoGrayPersistService, - new Timestamp(System.currentTimeMillis())); + new Timestamp(System.currentTimeMillis()), historyConfigInfoPersistService); } @Test diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java index 3877461c48e..b7e28653324 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoGrayPersistServiceImplTest.java @@ -18,10 +18,13 @@ import com.alibaba.nacos.common.utils.MD5Utils; import com.alibaba.nacos.config.server.constant.Constants; +import com.alibaba.nacos.config.server.model.ConfigAllInfo4Gray; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; import com.alibaba.nacos.persistence.model.Page; @@ -43,6 +46,7 @@ import java.util.Arrays; import java.util.List; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_GRAY_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -66,6 +70,12 @@ public class EmbeddedConfigInfoGrayPersistServiceImplTest { @Mock private DataSourceService dataSourceService; + @Mock + private IdGeneratorManager idGeneratorManager; + + @Mock + private HistoryConfigInfoPersistService historyConfigInfoPersistService; + MockedStatic envUtilMockedStatic; MockedStatic embeddedStorageContextHolderMockedStatic; @@ -91,7 +101,8 @@ public void before() { when(dataSourceService.getDataSourceType()).thenReturn("derby"); envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) .thenReturn(false); - embeddedConfigInfoGrayPersistService = new EmbeddedConfigInfoGrayPersistServiceImpl(databaseOperate); + embeddedConfigInfoGrayPersistService = new EmbeddedConfigInfoGrayPersistServiceImpl(databaseOperate, + idGeneratorManager, historyConfigInfoPersistService); } /** @@ -119,7 +130,7 @@ public void testInsertOrUpdateGrayOfAdd() { configInfoStateWrapper.setLastModified(System.currentTimeMillis()); configInfoStateWrapper.setId(234567890L); String grayName = "tag123grayName"; - String grayRule = "tag123grayrule"; + String grayRule = ""; Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(configInfoStateWrapper); @@ -131,10 +142,14 @@ public void testInsertOrUpdateGrayOfAdd() { //mock insert invoked. embeddedStorageContextHolderMockedStatic.verify( - () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), any(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), eq(appName), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class)), times(1)); + + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic( + eq(configInfo.getId()), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I"), + eq("gray"), anyString()); assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); @@ -155,11 +170,22 @@ public void testInsertOrUpdateGrayOfUpdate() { configInfoStateWrapper.setLastModified(System.currentTimeMillis()); configInfoStateWrapper.setId(234567890L); String grayName = "tag123grayName"; - String grayRule = "tag123grayrule"; + final String grayRule = "tag123grayrule"; Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) .thenReturn(configInfoStateWrapper); + + //mock exist config info + ConfigAllInfo4Gray configAllInfo4Gray = new ConfigAllInfo4Gray(); + configAllInfo4Gray.setDataId(dataId); + configAllInfo4Gray.setGroup(group); + configAllInfo4Gray.setTenant(tenant); + configAllInfo4Gray.setMd5("old_md5"); + configAllInfo4Gray.setSrcUser("user"); + when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_ALL_INFO_GRAY_ROW_MAPPER))).thenReturn(configAllInfo4Gray); + String srcIp = "ip345678"; String srcUser = "user1234567"; ConfigOperateResult configOperateResult = embeddedConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, @@ -170,6 +196,9 @@ public void testInsertOrUpdateGrayOfUpdate() { eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), any(Timestamp.class), eq(appName), eq(grayRule), eq(dataId), eq(group), eq(tenant), eq(grayName)), times(1)); + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic( + eq(configAllInfo4Gray.getId()), eq(configAllInfo4Gray), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("U"), + eq("gray"), anyString()); assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); @@ -191,7 +220,7 @@ public void testInsertOrUpdateGrayCasOfAdd() { configInfoStateWrapper.setLastModified(System.currentTimeMillis()); configInfoStateWrapper.setId(234567890L); String grayName = "tag123grayName"; - String grayRule = "tag123grayrule"; + String grayRule = ""; Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(null).thenReturn(configInfoStateWrapper); @@ -203,10 +232,13 @@ public void testInsertOrUpdateGrayCasOfAdd() { //verify insert to be invoked //mock insert invoked. embeddedStorageContextHolderMockedStatic.verify( - () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), any(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), eq(appName), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), any(Timestamp.class), any(Timestamp.class)), times(1)); + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic( + eq(configInfo.getId()), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I"), + eq("gray"), anyString()); assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); @@ -228,10 +260,21 @@ public void testInsertOrUpdateGrayCasOfUpdate() { configInfoStateWrapper.setLastModified(System.currentTimeMillis()); configInfoStateWrapper.setId(234567890L); String grayName = "tag123grayName"; - String grayRule = "tag123grayrule"; + final String grayRule = ""; Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper()) .thenReturn(configInfoStateWrapper); + + //mock exist config info + ConfigAllInfo4Gray configAllInfo4Gray = new ConfigAllInfo4Gray(); + configAllInfo4Gray.setDataId(dataId); + configAllInfo4Gray.setGroup(group); + configAllInfo4Gray.setTenant(tenant); + configAllInfo4Gray.setMd5("old_md5"); + configAllInfo4Gray.setSrcUser("user"); + when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_ALL_INFO_GRAY_ROW_MAPPER))).thenReturn(configAllInfo4Gray); + String srcIp = "ip345678"; String srcUser = "user1234567"; @@ -245,23 +288,41 @@ public void testInsertOrUpdateGrayCasOfUpdate() { eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), eq(srcUser), eq(appName), eq(grayRule), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(configInfo.getMd5())), times(1)); + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic( + eq(configAllInfo4Gray.getId()), eq(configAllInfo4Gray), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("U"), + eq("gray"), anyString()); assertEquals(configInfoStateWrapper.getId(), configOperateResult.getId()); assertEquals(configInfoStateWrapper.getLastModified(), configOperateResult.getLastModified()); } @Test - public void testRemoveConfigInfograyName() { + public void testRemoveConfigInfoGrayName() { String dataId = "dataId1112222"; String group = "group22"; String tenant = "tenant2"; - String grayName = "gray123345"; - String srcIp = "ip345678"; - String srcUser = "user1234567"; + final String srcIp = "ip345678"; + final String srcUser = "user1234567"; + final String grayName = "grayName..."; + + //mock exist config info + ConfigAllInfo4Gray configAllInfo4Gray = new ConfigAllInfo4Gray(); + configAllInfo4Gray.setDataId(dataId); + configAllInfo4Gray.setGroup(group); + configAllInfo4Gray.setTenant(tenant); + configAllInfo4Gray.setMd5("old_md5"); + + when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_ALL_INFO_GRAY_ROW_MAPPER))).thenReturn(configAllInfo4Gray); + embeddedConfigInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, grayName, srcIp, srcUser); + //verify delete sql invoked. embeddedStorageContextHolderMockedStatic.verify( () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName)), times(1)); + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic( + eq(configAllInfo4Gray.getId()), eq(configAllInfo4Gray), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("D"), + eq("gray"), anyString()); } @Test diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImplTest.java index b62a44521bb..a0dfa27aefe 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImplTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedConfigInfoPersistServiceImplTest.java @@ -28,6 +28,7 @@ import com.alibaba.nacos.config.server.model.ConfigOperateResult; import com.alibaba.nacos.config.server.model.SameConfigPolicy; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.core.distributed.id.IdGeneratorManager; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; @@ -153,8 +154,8 @@ void testInsertOrUpdateOfInsertConfigSuccess() { String srcIp = "srcIp"; String srcUser = "srcUser"; //mock insert config info - Mockito.doNothing().when(historyConfigInfoPersistService) - .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + Mockito.doNothing().when(historyConfigInfoPersistService).insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); ConfigOperateResult configOperateResult = embeddedConfigInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, configAdvanceInfo); @@ -176,7 +177,8 @@ void testInsertOrUpdateOfInsertConfigSuccess() { //expect insert history info Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I"), + eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); } @@ -233,7 +235,8 @@ void testInsertOrUpdateCasOfInsertConfigSuccess() { //expect insert history info Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I"), eq("formal"), + eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); } @Test @@ -266,15 +269,15 @@ void testInsertOrUpdateOfUpdateConfigSuccess() { .thenReturn(new ConfigInfoStateWrapper(), new ConfigInfoStateWrapper()); //mock select config info before update - ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); - configInfoWrapperOld.setDataId(dataId); - configInfoWrapperOld.setGroup(group); - configInfoWrapperOld.setTenant(tenant); - configInfoWrapperOld.setAppName("old_app"); - configInfoWrapperOld.setMd5("old_md5"); - configInfoWrapperOld.setId(12345678765L); - Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))) - .thenReturn(configInfoWrapperOld); + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + configAllInfo.setAppName("old_app"); + configAllInfo.setMd5("old_md5"); + configAllInfo.setId(12345678765L); + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_ALL_INFO_ROW_MAPPER))) + .thenReturn(configAllInfo); String srcIp = "srcIp"; String srcUser = "srcUser"; embeddedConfigInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, configAdvanceInfo); @@ -294,8 +297,8 @@ void testInsertOrUpdateOfUpdateConfigSuccess() { //expect insert history info of U Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), - any(Timestamp.class), eq("U")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("U"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); } @@ -331,15 +334,16 @@ void testInsertOrUpdateCasOfUpdateConfigSuccess() { .thenReturn(new ConfigInfoStateWrapper(), new ConfigInfoStateWrapper()); //mock select config info before update - ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); - configInfoWrapperOld.setDataId(dataId); - configInfoWrapperOld.setGroup(group); - configInfoWrapperOld.setTenant(tenant); - configInfoWrapperOld.setAppName("old_app11"); - configInfoWrapperOld.setMd5("old_md5"); - configInfoWrapperOld.setId(123456799L); - Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))) - .thenReturn(configInfoWrapperOld); + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + configAllInfo.setAppName("old_app"); + configAllInfo.setMd5("old_md5"); + configAllInfo.setId(12345678765L); + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_ALL_INFO_ROW_MAPPER))) + .thenReturn(configAllInfo); String srcIp = "srcIp"; String srcUser = "srcUser"; @@ -361,8 +365,8 @@ void testInsertOrUpdateCasOfUpdateConfigSuccess() { //expect insert history info of U Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), - any(Timestamp.class), eq("U")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("U"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); } @@ -373,17 +377,16 @@ void testRemoveConfigInfo() { String tenant = "tenant4567890"; //mock exist config info - ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); - configInfoWrapperOld.setDataId(dataId); - configInfoWrapperOld.setGroup(group); - configInfoWrapperOld.setTenant(tenant); - configInfoWrapperOld.setAppName("old_app"); - configInfoWrapperOld.setContent("old content"); - configInfoWrapperOld.setMd5("old_md5"); - configInfoWrapperOld.setId(12345678765L); - configInfoWrapperOld.setEncryptedDataKey("key3456"); - Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))) - .thenReturn(configInfoWrapperOld); + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + configAllInfo.setAppName("old_app"); + configAllInfo.setMd5("old_md5"); + configAllInfo.setId(12345678765L); + + Mockito.when(databaseOperate.queryOne(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_ALL_INFO_ROW_MAPPER))) + .thenReturn(configAllInfo); String srcIp = "srcIp1234"; String srcUser = "srcUser"; Mockito.when(databaseOperate.update(any())).thenReturn(true); @@ -394,11 +397,11 @@ void testRemoveConfigInfo() { () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(dataId), eq(group), eq(tenant)), times(1)); //expect delete config tag to be invoked embeddedStorageContextHolderMockedStatic.verify( - () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(configInfoWrapperOld.getId())), times(1)); + () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(configAllInfo.getId())), times(1)); //expect insert delete history Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfoWrapperOld), eq(srcIp), eq(srcUser), any(), - eq("D")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), eq(configAllInfo), eq(srcIp), eq(srcUser), any(), + eq("D"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); } @@ -406,13 +409,23 @@ void testRemoveConfigInfo() { void testRemoveConfigInfoByIds() { //mock exist config info - List configInfos = new ArrayList<>(); - configInfos.add(new ConfigInfo("data1", "group", "tenant", "app", "content")); - configInfos.add(new ConfigInfo("data2", "grou2", "tenan2", "app2", "content2")); + final List configAllInfos = new ArrayList<>(); + final ConfigAllInfo configAllInfo1 = new ConfigAllInfo(); + final ConfigAllInfo configAllInfo2 = new ConfigAllInfo(); + configAllInfo1.setDataId("dataId1"); + configAllInfo1.setGroup("group1"); + configAllInfo1.setTenant("tenant1"); + configAllInfo1.setAppName("app1"); + configAllInfo2.setDataId("dataId2"); + configAllInfo2.setGroup("group2"); + configAllInfo2.setTenant("tenant2"); + configAllInfo2.setAppName("app2"); + configAllInfos.add(configAllInfo1); + configAllInfos.add(configAllInfo2); List deleteIds = Arrays.asList(12344L, 3456789L); - configInfos.get(0).setId(12344L); - configInfos.get(1).setId(3456789L); - Mockito.when(databaseOperate.queryMany(anyString(), eq(deleteIds.toArray()), eq(CONFIG_INFO_ROW_MAPPER))).thenReturn(configInfos); + configAllInfos.get(0).setId(12344L); + configAllInfos.get(1).setId(3456789L); + Mockito.when(databaseOperate.queryMany(anyString(), eq(deleteIds.toArray()), eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(configAllInfos); String srcIp = "srcIp1234"; String srcUser = "srcUser"; Mockito.when(databaseOperate.update(any())).thenReturn(true); @@ -430,10 +443,13 @@ void testRemoveConfigInfoByIds() { embeddedStorageContextHolderMockedStatic.verify(() -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(deleteId1)), times(1)); //expect insert delete history + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic(eq(configAllInfos.get(0).getId()), + eq(configAllInfos.get(0)), eq(srcIp), eq(srcUser), any(), eq("D"), eq("formal"), + eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfos.get(0)))); Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfos.get(0).getId()), eq(configInfos.get(0)), eq(srcIp), eq(srcUser), any(), eq("D")); - Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfos.get(1).getId()), eq(configInfos.get(1)), eq(srcIp), eq(srcUser), any(), eq("D")); + .insertConfigHistoryAtomic(eq(configAllInfos.get(1).getId()), + eq(configAllInfos.get(1)), eq(srcIp), eq(srcUser), any(), eq("D"), eq("formal"), + eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfos.get(1)))); } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java index 47a33bf16a2..232d6e52038 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/embedded/EmbeddedHistoryConfigInfoPersistServiceImplTest.java @@ -38,7 +38,6 @@ import java.util.ArrayList; import java.util.List; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -102,16 +101,20 @@ void testInsertConfigHistoryAtomic() { String srcUser = "user12345"; String srcIp = "ip1234"; String ops = "D"; + String publishType = "formal"; + String extraInfo = "{\"type\":\"properties\"}"; Timestamp timestamp = new Timestamp(System.currentTimeMillis()); ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); configInfo.setEncryptedDataKey("key23456"); //expect insert success,verify insert invoked - embeddedHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, ops); + embeddedHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, ops, + publishType, extraInfo); //verify insert to be invoked embeddedStorageContextHolderMockedStatic.verify( () -> EmbeddedStorageContextHolder.addSqlContext(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), eq(appName), - eq(content), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), + eq(content), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), eq( + publishType), eq(extraInfo), eq(configInfo.getEncryptedDataKey())), times(1)); } @@ -129,38 +132,40 @@ void testRemoveConfigHistory() { void testFindDeletedConfig() { //mock query list return - ConfigInfoStateWrapper mockObj1 = new ConfigInfoStateWrapper(); + ConfigHistoryInfo mockObj1 = new ConfigHistoryInfo(); mockObj1.setDataId("data_id1"); mockObj1.setGroup("group_id1"); mockObj1.setTenant("tenant_id1"); mockObj1.setMd5("md51"); - mockObj1.setLastModified(System.currentTimeMillis()); + mockObj1.setLastModifiedTime(new Timestamp(System.currentTimeMillis())); - List list = new ArrayList<>(); + List list = new ArrayList<>(); list.add(mockObj1); - ConfigInfoStateWrapper mockObj2 = new ConfigInfoStateWrapper(); + ConfigHistoryInfo mockObj2 = new ConfigHistoryInfo(); mockObj2.setDataId("data_id2"); mockObj2.setGroup("group_id2"); mockObj2.setTenant("tenant_id2"); mockObj2.setMd5("md52"); + mockObj2.setLastModifiedTime(new Timestamp(System.currentTimeMillis())); list.add(mockObj2); int pageSize = 1233; long startId = 23456; Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {timestamp, startId, pageSize}), - eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(list); + String publishType = "formal"; + Mockito.when(databaseOperate.queryMany(anyString(), eq(new Object[] {publishType, timestamp, startId, pageSize}), + eq(HISTORY_DETAIL_ROW_MAPPER))).thenReturn(list); //execute List deletedConfig = embeddedHistoryConfigInfoPersistService.findDeletedConfig(timestamp, startId, - pageSize); + pageSize, "formal"); //expect verify assertEquals("data_id1", deletedConfig.get(0).getDataId()); assertEquals("group_id1", deletedConfig.get(0).getGroup()); assertEquals("tenant_id1", deletedConfig.get(0).getTenant()); - assertEquals(mockObj1.getLastModified(), deletedConfig.get(0).getLastModified()); + assertEquals(mockObj1.getLastModifiedTime(), new Timestamp(deletedConfig.get(0).getLastModified())); assertEquals("data_id2", deletedConfig.get(1).getDataId()); assertEquals("group_id2", deletedConfig.get(1).getGroup()); assertEquals("tenant_id2", deletedConfig.get(1).getTenant()); - assertEquals(mockObj2.getLastModified(), deletedConfig.get(1).getLastModified()); + assertEquals(mockObj2.getLastModifiedTime(), new Timestamp(deletedConfig.get(1).getLastModified())); } @Test diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java index 4bd2224e28c..370c57d9652 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoGrayPersistServiceImplTest.java @@ -17,15 +17,18 @@ package com.alibaba.nacos.config.server.service.repository.extrnal; import com.alibaba.nacos.common.utils.MD5Utils; +import com.alibaba.nacos.config.server.model.ConfigAllInfo4Gray; import com.alibaba.nacos.config.server.model.ConfigInfo; import com.alibaba.nacos.config.server.model.ConfigInfoGrayWrapper; import com.alibaba.nacos.config.server.model.ConfigInfoStateWrapper; import com.alibaba.nacos.config.server.model.ConfigOperateResult; +import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; import com.alibaba.nacos.config.server.utils.TestCaseUtils; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; import com.alibaba.nacos.persistence.model.Page; +import com.alibaba.nacos.persistence.repository.embedded.operate.DatabaseOperate; import com.alibaba.nacos.sys.env.EnvUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -45,11 +48,13 @@ import java.util.List; import static com.alibaba.nacos.config.server.constant.Constants.ENCODE; +import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_ALL_INFO_GRAY_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; @@ -66,6 +71,12 @@ public class ExternalConfigInfoGrayPersistServiceImplTest { @Mock private JdbcTemplate jdbcTemplate; + @Mock + private HistoryConfigInfoPersistService historyConfigInfoPersistService; + + @Mock + DatabaseOperate databaseOperate; + private TransactionTemplate transactionTemplate = TestCaseUtils.createMockTransactionTemplate(); MockedStatic envUtilMockedStatic; @@ -92,7 +103,7 @@ public void before() { when(dataSourceService.getDataSourceType()).thenReturn("mysql"); envUtilMockedStatic.when(() -> EnvUtil.getProperty(anyString(), eq(Boolean.class), eq(false))) .thenReturn(false); - externalConfigInfoGrayPersistService = new ExternalConfigInfoGrayPersistServiceImpl(); + externalConfigInfoGrayPersistService = new ExternalConfigInfoGrayPersistServiceImpl(historyConfigInfoPersistService); } /** @@ -110,6 +121,7 @@ public void testInsertOrUpdateGrayOfUpdate() { String dataId = "grayDataId113"; String group = "group"; String tenant = "tenant"; + //mock exist gray ConfigInfoStateWrapper mockedConfigInfoStateWrapper = new ConfigInfoStateWrapper(); mockedConfigInfoStateWrapper.setDataId(dataId); @@ -117,15 +129,22 @@ public void testInsertOrUpdateGrayOfUpdate() { mockedConfigInfoStateWrapper.setTenant(tenant); mockedConfigInfoStateWrapper.setId(123456L); mockedConfigInfoStateWrapper.setLastModified(System.currentTimeMillis()); + + //mock exist config info + ConfigAllInfo4Gray configAllInfo4Gray = new ConfigAllInfo4Gray(); + configAllInfo4Gray.setDataId(dataId); + configAllInfo4Gray.setGroup(group); + configAllInfo4Gray.setTenant(tenant); + configAllInfo4Gray.setMd5("old_md5"); String grayName = "grayName..."; when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), - eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper, - mockedConfigInfoStateWrapper); - //execute + eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(mockedConfigInfoStateWrapper); + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_ALL_INFO_GRAY_ROW_MAPPER))).thenReturn(configAllInfo4Gray); String srcIp = "srcUp..."; String srcUser = "srcUser..."; - String appName = "appname"; + String appName = "appName"; String content = "content111"; ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); configInfo.setEncryptedDataKey("key34567"); @@ -208,9 +227,9 @@ public void testInsertOrUpdateGrayOfException() { String grayRule = "grayRule..."; // mock update throw CannotGetJdbcConnectionException when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), - eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), - eq(dataId), eq(group), eq(tenant), eq(grayName))).thenThrow( - new CannotGetJdbcConnectionException("mock fail")); + eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), + eq(dataId), eq(group), eq(tenant), eq(grayName))).thenThrow( + new CannotGetJdbcConnectionException("mock fail")); //execute of update& expect. try { externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, grayName, grayRule, srcIp, srcUser); @@ -226,7 +245,7 @@ public void testInsertOrUpdateGrayOfException() { when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser))).thenThrow( - new CannotGetJdbcConnectionException("mock fail add")); + new CannotGetJdbcConnectionException("mock fail add")); //execute of add& expect. try { @@ -239,7 +258,7 @@ public void testInsertOrUpdateGrayOfException() { //mock query throw CannotGetJdbcConnectionException when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( - new CannotGetJdbcConnectionException("get c fail")); + new CannotGetJdbcConnectionException("get c fail")); //execute of add& expect. try { externalConfigInfoGrayPersistService.insertOrUpdateGray(configInfo, grayName, grayRule, srcIp, srcUser); @@ -283,6 +302,16 @@ public void testInsertOrUpdateGrayCasOfUpdate() { eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(configInfo.getMd5()))).thenReturn(1); + //mock exist config info + ConfigAllInfo4Gray configAllInfo4Gray = new ConfigAllInfo4Gray(); + configAllInfo4Gray.setDataId(dataId); + configAllInfo4Gray.setGroup(group); + configAllInfo4Gray.setTenant(tenant); + configAllInfo4Gray.setMd5("old_md5"); + String grayName1 = "grayName1..."; + when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_ALL_INFO_GRAY_ROW_MAPPER))).thenReturn(configAllInfo4Gray); + ConfigOperateResult configOperateResult = externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, grayName, grayRule, srcIp, srcUser); //expect return obj @@ -365,7 +394,7 @@ public void testInsertOrUpdateGrayCasOfException() { when(jdbcTemplate.update(anyString(), eq(configInfo.getContent()), eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser), eq(configInfo.getAppName()), eq(grayRule), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(configInfo.getMd5()))).thenThrow( - new CannotGetJdbcConnectionException("updat mock fail")); + new CannotGetJdbcConnectionException("updat mock fail")); //execute of update& expect. try { @@ -382,7 +411,7 @@ public void testInsertOrUpdateGrayCasOfException() { when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName), eq(grayRule), eq(configInfo.getAppName()), eq(configInfo.getContent()), eq(configInfo.getEncryptedDataKey()), eq(MD5Utils.md5Hex(content, ENCODE)), eq(srcIp), eq(srcUser))).thenThrow( - new CannotGetJdbcConnectionException("mock fail add")); + new CannotGetJdbcConnectionException("mock fail add")); //execute of add& expect. try { @@ -395,7 +424,7 @@ public void testInsertOrUpdateGrayCasOfException() { //mock query throw CannotGetJdbcConnectionException when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenThrow( - new CannotGetJdbcConnectionException("get c fail")); + new CannotGetJdbcConnectionException("get c fail")); //execute of add& expect. try { externalConfigInfoGrayPersistService.insertOrUpdateGrayCas(configInfo, grayName, grayRule, srcIp, srcUser); @@ -407,29 +436,37 @@ public void testInsertOrUpdateGrayCasOfException() { } @Test - public void testRemoveConfigInfo4Gray() { - String dataId = "dataId456789"; - String group = "group4567"; - String tenant = "tenant56789o0"; - - String srcIp = "srcUp..."; - String srcUser = "srcUser..."; - String grayName = "grayName1"; + void testRemoveConfigInfo() { + String dataId = "dataId4567"; + String group = "group3456789"; + String tenant = "tenant4567890"; + final String grayName = "grayName1"; + + //mock exist config info + ConfigAllInfo4Gray configAllInfo4Gray = new ConfigAllInfo4Gray(); + configAllInfo4Gray.setDataId(dataId); + configAllInfo4Gray.setGroup(group); + configAllInfo4Gray.setTenant(tenant); + configAllInfo4Gray.setMd5("old_md5"); + + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), + eq(CONFIG_ALL_INFO_GRAY_ROW_MAPPER))) + .thenReturn(configAllInfo4Gray); + Mockito.when(databaseOperate.update(any())).thenReturn(true); + + String srcIp = "srcIp1234"; + String srcUser = "srcUser"; externalConfigInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, grayName, srcIp, srcUser); - //verity Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName)); + Mockito.verify(historyConfigInfoPersistService, times(1)).insertConfigHistoryAtomic( + eq(configAllInfo4Gray.getId()), eq(configAllInfo4Gray), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("D"), + eq("gray"), anyString()); - //mock query throw CannotGetJdbcConnectionException - when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName))).thenThrow( - new CannotGetJdbcConnectionException("mock fail11111")); + // Test the exception handling for CannotGetJdbcConnectionException + when(jdbcTemplate.update(anyString(), eq(dataId), eq(group), eq(tenant), eq(grayName))) + .thenThrow(new CannotGetJdbcConnectionException("mock fail11111")); - try { - externalConfigInfoGrayPersistService.removeConfigInfoGray(dataId, group, tenant, grayName, srcIp, srcUser); - assertTrue(false); - } catch (Exception exception) { - assertEquals("mock fail11111", exception.getMessage()); - } } @Test @@ -486,7 +523,7 @@ public void testFindConfigInfo4Gray() { //mock query throw CannotGetJdbcConnectionException when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant, grayName}), eq(CONFIG_INFO_GRAY_WRAPPER_ROW_MAPPER))).thenThrow( - new CannotGetJdbcConnectionException("mock fail11111")); + new CannotGetJdbcConnectionException("mock fail11111")); try { externalConfigInfoGrayPersistService.findConfigInfo4Gray(dataId, group, tenant, grayName); assertTrue(false); diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java index bab2bc8cf48..f833002eb92 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalConfigInfoPersistServiceImplTest.java @@ -29,6 +29,7 @@ import com.alibaba.nacos.config.server.model.SameConfigPolicy; import com.alibaba.nacos.config.server.service.repository.HistoryConfigInfoPersistService; import com.alibaba.nacos.config.server.service.sql.ExternalStorageUtils; +import com.alibaba.nacos.config.server.utils.ConfigExtInfoUtil; import com.alibaba.nacos.config.server.utils.TestCaseUtils; import com.alibaba.nacos.persistence.datasource.DataSourceService; import com.alibaba.nacos.persistence.datasource.DynamicDataSource; @@ -161,7 +162,8 @@ void testInsertOrUpdateOfInsertConfigSuccess() { String srcUser = "srcUser"; //mock insert config info Mockito.doNothing().when(historyConfigInfoPersistService) - .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); externalConfigInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, configAdvanceInfo); //expect insert config info @@ -180,7 +182,8 @@ void testInsertOrUpdateOfInsertConfigSuccess() { //expect insert history info Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); } @@ -215,7 +218,8 @@ void testInsertOrUpdateCasOfInsertConfigSuccess() { String srcUser = "srcUser"; //mock insert config info Mockito.doNothing().when(historyConfigInfoPersistService) - .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + .insertConfigHistoryAtomic(eq(0), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); externalConfigInfoPersistService.insertOrUpdateCas(srcIp, srcUser, configInfo, configAdvanceInfo); //expect insert config info @@ -234,7 +238,8 @@ void testInsertOrUpdateCasOfInsertConfigSuccess() { //expect insert history info Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), eq("I")); + .insertConfigHistoryAtomic(eq(0L), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), + eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAdvanceInfoMap(configAdvanceInfo, srcUser))); } @@ -286,17 +291,18 @@ void testInsertOrUpdateOfUpdateConfigSuccess() { //mock get config state,first and second is not null Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper(), new ConfigInfoStateWrapper()); + + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + configAllInfo.setAppName("old_app"); + configAllInfo.setMd5("old_md5"); + configAllInfo.setId(12345678765L); + //mock get all config info + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(configAllInfo); - //mock select config info before update - ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); - configInfoWrapperOld.setDataId(dataId); - configInfoWrapperOld.setGroup(group); - configInfoWrapperOld.setTenant(tenant); - configInfoWrapperOld.setAppName("old_app"); - configInfoWrapperOld.setMd5("old_md5"); - configInfoWrapperOld.setId(12345678765L); - Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))) - .thenReturn(configInfoWrapperOld); String srcIp = "srcIp"; String srcUser = "srcUser"; //mock update config info @@ -304,7 +310,7 @@ void testInsertOrUpdateOfUpdateConfigSuccess() { TableConstant.CONFIG_INFO) .update(Arrays.asList("content", "md5", "src_ip", "src_user", "gmt_modified@NOW()", "app_name", "c_desc", "c_use", "effect", "type", "c_schema", "encrypted_data_key"), Arrays.asList("data_id", "group_id", "tenant_id"))), - eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(configInfoWrapperOld.getAppName()), + eq(configInfo.getContent()), eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(configAllInfo.getAppName()), eq(configAdvanceInfo.get("desc")), eq(configAdvanceInfo.get("use")), eq(configAdvanceInfo.get("effect")), eq(configAdvanceInfo.get("type")), eq(configAdvanceInfo.get("schema")), eq(encryptedDataKey), eq(configInfo.getDataId()), eq(configInfo.getGroup()), eq(tenant))).thenReturn(1); @@ -317,8 +323,8 @@ void testInsertOrUpdateOfUpdateConfigSuccess() { //mock insert his config info Mockito.doNothing().when(historyConfigInfoPersistService) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), - eq("I")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), eq(configInfo), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); externalConfigInfoPersistService.insertOrUpdate(srcIp, srcUser, configInfo, configAdvanceInfo); @@ -327,17 +333,17 @@ void testInsertOrUpdateOfUpdateConfigSuccess() { externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION) .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), - eq(configInfoWrapperOld.getId()), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + eq(configAllInfo.getId()), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); Mockito.verify(jdbcTemplate, times(1)).update(eq( externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION) .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), - eq(configInfoWrapperOld.getId()), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + eq(configAllInfo.getId()), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); //expect insert history info Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), - any(Timestamp.class), eq("U")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), any(ConfigInfo.class), eq(srcIp), + eq(srcUser), any(Timestamp.class), eq("U"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); } @@ -364,40 +370,42 @@ void testInsertOrUpdateCasOfUpdateConfigSuccess() { Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))).thenReturn(new ConfigInfoStateWrapper(), new ConfigInfoStateWrapper()); - //mock select config info before update - ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); - configInfoWrapperOld.setDataId(dataId); - configInfoWrapperOld.setGroup(group); - configInfoWrapperOld.setTenant(tenant); - configInfoWrapperOld.setAppName("old_app11"); - configInfoWrapperOld.setMd5("old_md5"); - configInfoWrapperOld.setId(123456799L); - Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[]{dataId, group, tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))) - .thenReturn(configInfoWrapperOld); + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + configAllInfo.setAppName("old_app"); + configAllInfo.setMd5("old_md5"); + configAllInfo.setId(12345678765L); + //mock get all config info + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(configAllInfo); + String srcIp = "srcIp"; String srcUser = "srcUser"; //mock update config info cas Mockito.when(jdbcTemplate.update(anyString(), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), - eq(srcIp), eq(srcUser), eq(configInfoWrapperOld.getAppName()), eq(configAdvanceInfo.get("desc")), + eq(srcIp), eq(srcUser), eq(configAllInfo.getAppName()), eq(configAdvanceInfo.get("desc")), eq(configAdvanceInfo.get("use")), eq(configAdvanceInfo.get("effect")), eq(configAdvanceInfo.get("type")), eq(configAdvanceInfo.get("schema")), eq(encryptedDataKey), eq(dataId), eq(group), eq(tenant), eq(casMd5))).thenReturn(1); //mock insert config tags. Mockito.when(jdbcTemplate.update(eq(externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION) - .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), eq(configInfoWrapperOld.getId()), - anyString(), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant))).thenReturn(1); - + .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), + eq(configAllInfo.getId()), anyString(), eq(StringUtils.EMPTY), eq(dataId), eq(group), + eq(tenant))).thenReturn(1); + //mock insert his config info Mockito.doNothing().when(historyConfigInfoPersistService) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfo), eq(srcIp), eq(srcUser), any(Timestamp.class), - eq("I")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), eq(configInfo), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("I"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); externalConfigInfoPersistService.insertOrUpdateCas(srcIp, srcUser, configInfo, configAdvanceInfo); //expect update config cas Mockito.verify(jdbcTemplate, times(1)) .update(anyString(), eq(content), eq(MD5Utils.md5Hex(content, Constants.PERSIST_ENCODE)), eq(srcIp), - eq(srcUser), eq(configInfoWrapperOld.getAppName()), eq(configAdvanceInfo.get("desc")), + eq(srcUser), eq(configAllInfo.getAppName()), eq(configAdvanceInfo.get("desc")), eq(configAdvanceInfo.get("use")), eq(configAdvanceInfo.get("effect")), eq(configAdvanceInfo.get("type")), eq(configAdvanceInfo.get("schema")), eq(encryptedDataKey), eq(dataId), eq(group), eq(tenant), eq(casMd5)); @@ -406,17 +414,17 @@ void testInsertOrUpdateCasOfUpdateConfigSuccess() { externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION) .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), - eq(configInfoWrapperOld.getId()), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + eq(configAllInfo.getId()), eq("tag1"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); Mockito.verify(jdbcTemplate, times(1)).update(eq( externalConfigInfoPersistService.mapperManager.findMapper(dataSourceService.getDataSourceType(), TableConstant.CONFIG_TAGS_RELATION) .insert(Arrays.asList("id", "tag_name", "tag_type", "data_id", "group_id", "tenant_id"))), - eq(configInfoWrapperOld.getId()), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); + eq(configAllInfo.getId()), eq("tag2"), eq(StringUtils.EMPTY), eq(dataId), eq(group), eq(tenant)); //expect insert history info Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), - any(Timestamp.class), eq("U")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), any(ConfigInfo.class), eq(srcIp), eq(srcUser), + any(Timestamp.class), eq("U"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); } @@ -455,18 +463,18 @@ void testRemoveConfigInfo() { String group = "group3456789"; String tenant = "tenant4567890"; - //mock exist config info - ConfigInfoWrapper configInfoWrapperOld = new ConfigInfoWrapper(); - configInfoWrapperOld.setDataId(dataId); - configInfoWrapperOld.setGroup(group); - configInfoWrapperOld.setTenant(tenant); - configInfoWrapperOld.setAppName("old_app"); - configInfoWrapperOld.setContent("old content"); - configInfoWrapperOld.setMd5("old_md5"); - configInfoWrapperOld.setId(12345678765L); - configInfoWrapperOld.setEncryptedDataKey("key3456"); - Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), eq(CONFIG_INFO_WRAPPER_ROW_MAPPER))) - .thenReturn(configInfoWrapperOld); + //mock exist all config info + ConfigAllInfo configAllInfo = new ConfigAllInfo(); + configAllInfo.setDataId(dataId); + configAllInfo.setGroup(group); + configAllInfo.setTenant(tenant); + configAllInfo.setAppName("old_app"); + configAllInfo.setMd5("old_md5"); + configAllInfo.setId(12345678765L); + + Mockito.when(jdbcTemplate.queryForObject(anyString(), eq(new Object[] {dataId, group, tenant}), + eq(CONFIG_ALL_INFO_ROW_MAPPER))).thenReturn(configAllInfo); + String srcIp = "srcIp1234"; String srcUser = "srcUser"; externalConfigInfoPersistService.removeConfigInfo(dataId, group, tenant, srcIp, srcUser); @@ -474,11 +482,11 @@ void testRemoveConfigInfo() { //expect delete to be invoked Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(dataId), eq(group), eq(tenant)); //expect delete tags to be invoked - Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(configInfoWrapperOld.getId())); + Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(configAllInfo.getId())); //expect insert delete history Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfoWrapperOld.getId()), eq(configInfoWrapperOld), eq(srcIp), eq(srcUser), any(), - eq("D")); + .insertConfigHistoryAtomic(eq(configAllInfo.getId()), eq(configAllInfo), eq(srcIp), + eq(srcUser), any(), eq("D"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfo))); } @@ -486,13 +494,24 @@ void testRemoveConfigInfo() { void testRemoveConfigInfoByIds() { //mock exist config info - List configInfos = new ArrayList<>(); - configInfos.add(new ConfigInfo("data1", "group", "tenant", "app", "content")); - configInfos.add(new ConfigInfo("data2", "grou2", "tenan2", "app2", "content2")); + final List configAllInfos = new ArrayList<>(); + final ConfigAllInfo configAllInfo1 = new ConfigAllInfo(); + final ConfigAllInfo configAllInfo2 = new ConfigAllInfo(); + configAllInfo1.setDataId("dataId1"); + configAllInfo1.setGroup("group1"); + configAllInfo1.setTenant("tenant1"); + configAllInfo1.setAppName("app1"); + configAllInfo2.setDataId("dataId2"); + configAllInfo2.setGroup("group2"); + configAllInfo2.setTenant("tenant2"); + configAllInfo2.setAppName("app2"); + configAllInfos.add(configAllInfo1); + configAllInfos.add(configAllInfo2); List deleteIds = Arrays.asList(12344L, 3456789L); - configInfos.get(0).setId(12344L); - configInfos.get(1).setId(3456789L); - Mockito.when(jdbcTemplate.query(anyString(), eq(deleteIds.toArray()), eq(CONFIG_INFO_ROW_MAPPER))).thenReturn(configInfos); + configAllInfos.get(0).setId(12344L); + configAllInfos.get(1).setId(3456789L); + Mockito.when(jdbcTemplate.query(anyString(), eq(deleteIds.toArray()), eq(CONFIG_ALL_INFO_ROW_MAPPER))) + .thenReturn(configAllInfos); String srcIp = "srcIp1234"; String srcUser = "srcUser"; externalConfigInfoPersistService.removeConfigInfoByIds(deleteIds, srcIp, srcUser); @@ -504,9 +523,11 @@ void testRemoveConfigInfoByIds() { Mockito.verify(jdbcTemplate, times(1)).update(anyString(), eq(deleteIds.get(1))); //expect insert delete history Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfos.get(0).getId()), eq(configInfos.get(0)), eq(srcIp), eq(srcUser), any(), eq("D")); + .insertConfigHistoryAtomic(eq(configAllInfos.get(0).getId()), eq(configAllInfos.get(0)), eq(srcIp), eq(srcUser), + any(), eq("D"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfos.get(0)))); Mockito.verify(historyConfigInfoPersistService, times(1)) - .insertConfigHistoryAtomic(eq(configInfos.get(1).getId()), eq(configInfos.get(1)), eq(srcIp), eq(srcUser), any(), eq("D")); + .insertConfigHistoryAtomic(eq(configAllInfos.get(1).getId()), eq(configAllInfos.get(1)), + eq(srcIp), eq(srcUser), any(), eq("D"), eq("formal"), eq(ConfigExtInfoUtil.getExtraInfoFromAllInfo(configAllInfos.get(0)))); } diff --git a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java index e7509fd31ba..85bdaee3a22 100644 --- a/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java +++ b/config/src/test/java/com/alibaba/nacos/config/server/service/repository/extrnal/ExternalHistoryConfigInfoPersistServiceImplTest.java @@ -42,7 +42,6 @@ import java.util.ArrayList; import java.util.List; -import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_DETAIL_ROW_MAPPER; import static com.alibaba.nacos.config.server.service.repository.ConfigRowMapperInjector.HISTORY_LIST_ROW_MAPPER; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -107,20 +106,21 @@ void testInsertConfigHistoryAtomic() { String srcUser = "user12345"; String srcIp = "ip1234"; String ops = "D"; + String extraInfo = "type\":\"properties"; Timestamp timestamp = new Timestamp(System.currentTimeMillis()); ConfigInfo configInfo = new ConfigInfo(dataId, group, tenant, appName, content); configInfo.setEncryptedDataKey("key23456"); //expect insert success,verify insert invoked - externalHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, ops); + externalHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, ops, "formal", extraInfo); Mockito.verify(jdbcTemplate, times(1)) .update(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), eq(appName), eq(content), eq(configInfo.getMd5()), - eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), eq(configInfo.getEncryptedDataKey())); + eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), eq("formal"), eq(extraInfo), eq(configInfo.getEncryptedDataKey())); - Mockito.when(jdbcTemplate.update(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), eq(appName), eq(content), - eq(configInfo.getMd5()), eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), eq(configInfo.getEncryptedDataKey()))) + Mockito.when(jdbcTemplate.update(anyString(), eq(id), eq(dataId), eq(group), eq(tenant), eq(appName), eq(content), eq(configInfo.getMd5()), + eq(srcIp), eq(srcUser), eq(timestamp), eq(ops), eq("formal"), eq(extraInfo), eq(configInfo.getEncryptedDataKey()))) .thenThrow(new CannotGetJdbcConnectionException("mock ex...")); try { - externalHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, ops); + externalHistoryConfigInfoPersistService.insertConfigHistoryAtomic(id, configInfo, srcIp, srcUser, timestamp, ops, "formal", extraInfo); assertTrue(false); } catch (Exception e) { assertEquals("mock ex...", e.getMessage()); @@ -140,47 +140,49 @@ void testRemoveConfigHistory() { void testFindDeletedConfig() { //mock query list return - ConfigInfoStateWrapper mockObj1 = new ConfigInfoStateWrapper(); + ConfigHistoryInfo mockObj1 = new ConfigHistoryInfo(); mockObj1.setDataId("data_id1"); mockObj1.setGroup("group_id1"); mockObj1.setTenant("tenant_id1"); mockObj1.setMd5("md51"); - mockObj1.setLastModified(System.currentTimeMillis()); + mockObj1.setLastModifiedTime(new Timestamp(System.currentTimeMillis())); - List list = new ArrayList<>(); + List list = new ArrayList<>(); list.add(mockObj1); - ConfigInfoStateWrapper mockObj2 = new ConfigInfoStateWrapper(); + ConfigHistoryInfo mockObj2 = new ConfigHistoryInfo(); mockObj2.setDataId("data_id2"); mockObj2.setGroup("group_id2"); mockObj2.setTenant("tenant_id2"); mockObj2.setMd5("md52"); + mockObj2.setLastModifiedTime(new Timestamp(System.currentTimeMillis())); list.add(mockObj2); int pageSize = 1233; long startId = 23456; Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + String publishType = "formal"; Mockito.when( - jdbcTemplate.query(anyString(), eq(new Object[] {timestamp, startId, pageSize}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) + jdbcTemplate.query(anyString(), eq(new Object[] {publishType, timestamp, startId, pageSize}), eq(HISTORY_DETAIL_ROW_MAPPER))) .thenReturn(list); //execute List deletedConfig = externalHistoryConfigInfoPersistService.findDeletedConfig(timestamp, startId, - pageSize); + pageSize, "formal"); //expect verify assertEquals("data_id1", deletedConfig.get(0).getDataId()); assertEquals("group_id1", deletedConfig.get(0).getGroup()); assertEquals("tenant_id1", deletedConfig.get(0).getTenant()); - assertEquals(mockObj1.getLastModified(), deletedConfig.get(0).getLastModified()); + assertEquals(mockObj1.getLastModifiedTime(), new Timestamp(deletedConfig.get(0).getLastModified())); assertEquals("data_id2", deletedConfig.get(1).getDataId()); assertEquals("group_id2", deletedConfig.get(1).getGroup()); assertEquals("tenant_id2", deletedConfig.get(1).getTenant()); - assertEquals(mockObj2.getLastModified(), deletedConfig.get(1).getLastModified()); + assertEquals(mockObj2.getLastModifiedTime(), new Timestamp(deletedConfig.get(1).getLastModified())); //mock exception Mockito.when( - jdbcTemplate.query(anyString(), eq(new Object[] {timestamp, startId, pageSize}), eq(CONFIG_INFO_STATE_WRAPPER_ROW_MAPPER))) - .thenThrow(new CannotGetJdbcConnectionException("conn error")); + jdbcTemplate.query(anyString(), eq(new Object[] {publishType, timestamp, startId, pageSize}), + eq(HISTORY_DETAIL_ROW_MAPPER))).thenThrow(new CannotGetJdbcConnectionException("conn error")); try { - externalHistoryConfigInfoPersistService.findDeletedConfig(timestamp, startId, pageSize); + externalHistoryConfigInfoPersistService.findDeletedConfig(timestamp, startId, pageSize, "formal"); assertTrue(false); } catch (Exception e) { assertEquals("conn error", e.getMessage()); diff --git a/console-ui/src/locales/en-US.js b/console-ui/src/locales/en-US.js index e6e98efaf57..d63b800fa98 100644 --- a/console-ui/src/locales/en-US.js +++ b/console-ui/src/locales/en-US.js @@ -253,6 +253,9 @@ const I18N_CONF = { lastUpdateTime: 'Last Modified At', operator: 'Operator', operation: 'Operation', + publishType: 'Publish Type', + formal: 'Formal Version', + gray: 'Gray Version', compare: 'Compare', historyCompareTitle: 'History Compare', historyCompareLastVersion: 'Lasted Release Version', @@ -272,6 +275,11 @@ const I18N_CONF = { configureContent: 'Configuration Content', back: 'Back', namespace: 'Namespace', + publishType: 'Publish Type', + formal: 'Formal Version', + gray: 'Gray Version', + grayVersion: 'Gray Version', + grayRule: 'Gray Rule', }, DashboardCard: { importantReminder0: 'Important reminder', diff --git a/console-ui/src/locales/zh-CN.js b/console-ui/src/locales/zh-CN.js index 2a8cb3b3377..a92cca7a612 100644 --- a/console-ui/src/locales/zh-CN.js +++ b/console-ui/src/locales/zh-CN.js @@ -250,6 +250,9 @@ const I18N_CONF = { articleMeetRequirements: '条满足要求的配置。', lastUpdateTime: '最后更新时间', operator: '操作人', + publishType: '发布类型', + formal: '正式版本', + gray: '灰度版本', operation: '操作', compare: '比较', historyCompareTitle: '历史版本比较', @@ -270,6 +273,11 @@ const I18N_CONF = { sourceIp: '来源 IP', back: '返回', namespace: '命名空间', + publishType: '发布类型', + formal: '正式版本', + gray: '灰度版本', + grayVersion: '灰度版本', + grayRule: '灰度规则', }, DashboardCard: { importantReminder0: '重要提醒', diff --git a/console-ui/src/pages/ConfigurationManagement/ConfigRollback/ConfigRollback.js b/console-ui/src/pages/ConfigurationManagement/ConfigRollback/ConfigRollback.js index 9d058df05e5..ce76786fe96 100644 --- a/console-ui/src/pages/ConfigurationManagement/ConfigRollback/ConfigRollback.js +++ b/console-ui/src/pages/ConfigurationManagement/ConfigRollback/ConfigRollback.js @@ -39,6 +39,7 @@ class ConfigRollback extends React.Component { envName: '', visible: false, showmore: false, + extraInfo: {}, }; // this.params = window.location.hash.split('?')[1]||''; } @@ -93,6 +94,7 @@ class ConfigRollback extends React.Component { self.field.setValue('envName', envName); self.setState({ envName, + extraInfo: data.extraInfo ? JSON.parse(data.extraInfo) : {}, }); } }, @@ -138,12 +140,19 @@ class ConfigRollback extends React.Component { self.serverId = getParams('serverId') || 'center'; self.dataId = self.field.getValue('dataId'); self.group = self.field.getValue('group'); + const { extraInfo } = self.state; let postData = { appName: self.field.getValue('appName'), dataId: self.dataId, group: self.group, content: self.field.getValue('content'), tenant: self.tenant, + ...(extraInfo.type ? { type: extraInfo.type } : {}), + ...(extraInfo.config_tags ? { config_tags: extraInfo.config_tags } : {}), + ...(extraInfo.effect ? { effect: extraInfo.effect } : {}), + ...(extraInfo.c_desc ? { desc: extraInfo.c_desc } : {}), + ...(extraInfo.c_use ? { use: extraInfo.c_use } : {}), + ...(extraInfo.c_schema ? { schema: extraInfo.c_schema } : {}), }; let url = 'v1/cs/configs'; diff --git a/console-ui/src/pages/ConfigurationManagement/HistoryDetail/HistoryDetail.js b/console-ui/src/pages/ConfigurationManagement/HistoryDetail/HistoryDetail.js index 19b0cecb763..c51afc793ec 100644 --- a/console-ui/src/pages/ConfigurationManagement/HistoryDetail/HistoryDetail.js +++ b/console-ui/src/pages/ConfigurationManagement/HistoryDetail/HistoryDetail.js @@ -34,6 +34,9 @@ class HistoryDetail extends React.Component { super(props); this.state = { showmore: false, + currentPublishType: '', + grayVersion: '', + grayRule: '', }; this.edasAppName = getParams('edasAppName'); this.edasAppId = getParams('edasAppId'); @@ -74,6 +77,13 @@ class HistoryDetail extends React.Component { self.field.setValue('opType', data.opType.trim()); self.field.setValue('group', data.group); self.field.setValue('md5', data.md5); + self.setState({ + currentPublishType: data.publishType, + ...(data.publishType === 'gray' && { + grayVersion: JSON.parse(data.extraInfo || '{}').version || '', + grayRule: JSON.parse(data.extraInfo || '{}').expr || '', + }), + }); } }, }); @@ -100,6 +110,7 @@ class HistoryDetail extends React.Component { render() { const { locale = {} } = this.props; const { init } = this.field; + const { currentPublishType, grayVersion, grayRule } = this.state; const formItemLayout = { labelCol: { fixedSpan: 6, @@ -132,6 +143,23 @@ class HistoryDetail extends React.Component { + + + + {currentPublishType === 'gray' && ( + <> + + + + + + + + )} diff --git a/console-ui/src/pages/ConfigurationManagement/HistoryRollback/HistoryRollback.js b/console-ui/src/pages/ConfigurationManagement/HistoryRollback/HistoryRollback.js index 4fe7f28d98b..72c677cc299 100644 --- a/console-ui/src/pages/ConfigurationManagement/HistoryRollback/HistoryRollback.js +++ b/console-ui/src/pages/ConfigurationManagement/HistoryRollback/HistoryRollback.js @@ -133,13 +133,21 @@ class HistoryRollback extends React.Component { renderCol(value, index, record) { const { locale = {} } = this.props; + const isBeta = record.publishType === 'gray'; return (
{locale.details} | - + {locale.rollback} | @@ -431,6 +439,23 @@ class HistoryRollback extends React.Component { + { + if (value === 'formal') { + return locale.formal; + } else if (value === 'gray') { + const extraInfo = record.extraInfo ? JSON.parse(record.extraInfo) : {}; + if (extraInfo.gray_name) { + return `${locale.gray}(${extraInfo.gray_name})`; + } else { + return locale.gray; + } + } + return value; + }} + /> .next-btn-icon.next-icon-alone .next-icon-remote,.next-btn.next-medium>.next-btn-icon.next-icon-alone:before,.next-btn.next-medium>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-medium>.next-btn-icon.next-icon-first:before,.next-btn.next-medium>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-medium>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px}.next-btn.next-medium.next-btn-loading:before{width:12px;height:12px;font-size:12px;line-height:12px;left:12px}.next-btn.next-medium>.next-btn-custom-loading-icon.show{width:12px}.next-btn.next-large{padding:0 16px}.next-btn.next-large>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn.next-large>.next-btn-icon.next-icon-alone:before,.next-btn.next-large>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-large>.next-btn-icon.next-icon-first:before,.next-btn.next-large>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-large>.next-btn-icon.next-icon-last:before{width:16px;font-size:16px}.next-btn.next-large.next-btn-loading:before{width:16px;height:16px;font-size:16px;line-height:16px;left:16px}.next-btn.next-large>.next-btn-custom-loading-icon.show{width:16px}.next-btn.next-btn-normal{border-color:#c4c6cf}.next-btn.next-btn-normal.active,.next-btn.next-btn-normal.hover,.next-btn.next-btn-normal:active,.next-btn.next-btn-normal:focus,.next-btn.next-btn-normal:hover{background:#f2f3f7;border-color:#a0a2ad}.next-btn.next-btn-primary{background:#5584ff}.next-btn.next-btn-primary.active,.next-btn.next-btn-primary.hover,.next-btn.next-btn-primary:active,.next-btn.next-btn-primary:focus,.next-btn.next-btn-primary:hover{background:#3e71f7}.next-btn.next-btn-secondary{border-color:#5584ff}.next-btn.next-btn-secondary,.next-btn.next-btn-secondary.visited,.next-btn.next-btn-secondary:link,.next-btn.next-btn-secondary:visited{color:#5584ff}.next-btn.next-btn-secondary.active,.next-btn.next-btn-secondary.hover,.next-btn.next-btn-secondary:active,.next-btn.next-btn-secondary:focus,.next-btn.next-btn-secondary:hover{background:#3e71f7;border-color:#3e71f7}.next-btn.disabled.next-btn-normal,.next-btn.disabled.next-btn-normal.active,.next-btn.disabled.next-btn-normal.hover,.next-btn.disabled.next-btn-normal:active,.next-btn.disabled.next-btn-normal:focus,.next-btn.disabled.next-btn-normal:hover,.next-btn.disabled.next-btn-primary,.next-btn.disabled.next-btn-primary.active,.next-btn.disabled.next-btn-primary.hover,.next-btn.disabled.next-btn-primary:active,.next-btn.disabled.next-btn-primary:focus,.next-btn.disabled.next-btn-primary:hover,.next-btn.disabled.next-btn-secondary,.next-btn.disabled.next-btn-secondary.active,.next-btn.disabled.next-btn-secondary.hover,.next-btn.disabled.next-btn-secondary:active,.next-btn.disabled.next-btn-secondary:focus,.next-btn.disabled.next-btn-secondary:hover,.next-btn[disabled].next-btn-normal,.next-btn[disabled].next-btn-normal.active,.next-btn[disabled].next-btn-normal.hover,.next-btn[disabled].next-btn-normal:active,.next-btn[disabled].next-btn-normal:focus,.next-btn[disabled].next-btn-normal:hover,.next-btn[disabled].next-btn-primary,.next-btn[disabled].next-btn-primary.active,.next-btn[disabled].next-btn-primary.hover,.next-btn[disabled].next-btn-primary:active,.next-btn[disabled].next-btn-primary:focus,.next-btn[disabled].next-btn-primary:hover,.next-btn[disabled].next-btn-secondary,.next-btn[disabled].next-btn-secondary.active,.next-btn[disabled].next-btn-secondary.hover,.next-btn[disabled].next-btn-secondary:active,.next-btn[disabled].next-btn-secondary:focus,.next-btn[disabled].next-btn-secondary:hover{background:#f7f8fa;border-color:#e6e7eb}.next-btn-warning.next-btn-primary{background:#ff3000;border-color:#ff3000}.next-btn-warning.next-btn-primary.active,.next-btn-warning.next-btn-primary.hover,.next-btn-warning.next-btn-primary:active,.next-btn-warning.next-btn-primary:focus,.next-btn-warning.next-btn-primary:hover{background:#e72b00;border-color:#e72b00}.next-btn-warning.next-btn-primary.disabled,.next-btn-warning.next-btn-primary.disabled.active,.next-btn-warning.next-btn-primary.disabled.hover,.next-btn-warning.next-btn-primary.disabled:active,.next-btn-warning.next-btn-primary.disabled:focus,.next-btn-warning.next-btn-primary.disabled:hover,.next-btn-warning.next-btn-primary[disabled],.next-btn-warning.next-btn-primary[disabled].active,.next-btn-warning.next-btn-primary[disabled].hover,.next-btn-warning.next-btn-primary[disabled]:active,.next-btn-warning.next-btn-primary[disabled]:focus,.next-btn-warning.next-btn-primary[disabled]:hover{background:#f7f8fa;border-color:#dcdee3}.next-btn-warning.next-btn-normal{border-color:#ff3000}.next-btn-warning.next-btn-normal,.next-btn-warning.next-btn-normal.visited,.next-btn-warning.next-btn-normal:link,.next-btn-warning.next-btn-normal:visited{color:#ff3000}.next-btn-warning.next-btn-normal.active,.next-btn-warning.next-btn-normal.hover,.next-btn-warning.next-btn-normal:active,.next-btn-warning.next-btn-normal:focus,.next-btn-warning.next-btn-normal:hover{background:#e72b00;border-color:#e72b00}.next-btn-warning.next-btn-normal.disabled,.next-btn-warning.next-btn-normal.disabled.active,.next-btn-warning.next-btn-normal.disabled.hover,.next-btn-warning.next-btn-normal.disabled:active,.next-btn-warning.next-btn-normal.disabled:focus,.next-btn-warning.next-btn-normal.disabled:hover,.next-btn-warning.next-btn-normal[disabled],.next-btn-warning.next-btn-normal[disabled].active,.next-btn-warning.next-btn-normal[disabled].hover,.next-btn-warning.next-btn-normal[disabled]:active,.next-btn-warning.next-btn-normal[disabled]:focus,.next-btn-warning.next-btn-normal[disabled]:hover{background:#f7f8fa;border-color:#e6e7eb}.next-btn-text.next-btn-primary,.next-btn-text.next-btn-primary.visited,.next-btn-text.next-btn-primary:link,.next-btn-text.next-btn-primary:visited{color:#5584ff}.next-btn-text.next-btn-primary.active,.next-btn-text.next-btn-primary.hover,.next-btn-text.next-btn-primary:active,.next-btn-text.next-btn-primary:focus,.next-btn-text.next-btn-primary:hover{color:#3e71f7}.next-btn-text.next-btn-normal.active,.next-btn-text.next-btn-normal.hover,.next-btn-text.next-btn-normal:active,.next-btn-text.next-btn-normal:focus,.next-btn-text.next-btn-normal:hover,.next-btn-text.next-btn-secondary.active,.next-btn-text.next-btn-secondary.hover,.next-btn-text.next-btn-secondary:active,.next-btn-text.next-btn-secondary:focus,.next-btn-text.next-btn-secondary:hover{color:#5584ff}.next-btn-text.next-large>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn-text.next-large>.next-btn-icon.next-icon-alone:before,.next-btn-text.next-large>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text.next-large>.next-btn-icon.next-icon-first:before,.next-btn-text.next-large>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text.next-large>.next-btn-icon.next-icon-last:before{width:16px;font-size:16px}.next-btn-text.next-large.next-btn-loading:before{width:16px;height:16px;font-size:16px;line-height:16px}.next-btn-text.next-large>.next-btn-custom-loading-icon.show{width:16px}.next-btn-text.next-medium{font-size:12px}.next-btn-text.next-medium>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn-text.next-medium>.next-btn-icon.next-icon-alone:before,.next-btn-text.next-medium>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text.next-medium>.next-btn-icon.next-icon-first:before,.next-btn-text.next-medium>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text.next-medium>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px}.next-btn-text.next-medium.next-btn-loading:before{width:12px;height:12px;font-size:12px;line-height:12px}.next-btn-text.next-medium>.next-btn-custom-loading-icon.show{width:12px}.next-btn-group>.next-btn-primary:not(:first-child).disabled,.next-btn-group>.next-btn-primary:not(:first-child)[disabled]{border-left-color:#e6e7eb}.next-btn-group[dir=rtl]>.next-btn-primary:not(:first-child).disabled,.next-btn-group[dir=rtl]>.next-btn-primary:not(:first-child)[disabled]{border-right-color:#e6e7eb}.next-btn.next-small[dir=rtl].next-btn-loading{padding-left:8px;padding-right:24px}.next-btn.next-small[dir=rtl].next-btn-loading:after{right:8px}.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-first:before,.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px}.next-btn.next-medium[dir=rtl].next-btn-loading{padding-left:12px;padding-right:28px}.next-btn.next-medium[dir=rtl].next-btn-loading:after{right:12px}.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-first:before,.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-last:before{width:16px;font-size:16px}.next-btn.next-large[dir=rtl].next-btn-loading{padding-left:16px;padding-right:36px}.next-btn.next-large[dir=rtl].next-btn-loading:after{right:16px}.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-first:before,.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-last:before{width:16px;font-size:16px}.next-btn-text[dir=rtl].next-large.next-btn-loading{padding-right:20px}.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-first:before,.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px}.next-btn-text[dir=rtl].next-medium.next-btn-loading{padding-right:16px}.next-dialog{border:1px solid #dcdee3;border-radius:3px;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)}.next-dialog-body{font-size:12px}.next-dialog-close .next-dialog-close-icon.next-icon{margin-top:-6px;margin-left:-6px;width:12px;height:12px}.next-dialog-close .next-dialog-close-icon.next-icon:before{width:12px;height:12px;font-size:12px}.next-radio-wrapper .next-radio-inner{border:1px solid #c4c6cf}.next-radio-wrapper.checked .next-radio-inner{border-color:#5584ff;background:#5584ff}.next-radio-wrapper.disabled .next-radio-inner{border-color:#e6e7eb;background:#f7f8fa}.next-radio-wrapper.disabled .next-radio-inner.hovered,.next-radio-wrapper.disabled .next-radio-inner:hover{border-color:#e6e7eb}.next-radio-wrapper.disabled.checked .next-radio-inner{border-color:#e6e7eb;background:#f7f8fa}.next-radio-wrapper:not(.disabled).hovered .next-radio-inner,.next-radio-wrapper:not(.disabled):hover .next-radio-inner{border-color:#5584ff;background-color:#dee8ff}.next-radio-wrapper.checked:not(.disabled).hovered .next-radio-inner,.next-radio-wrapper.checked:not(.disabled):hover .next-radio-inner{background:#3e71f7}.next-radio-button>label{border:1px solid #c4c6cf}.next-radio-button>label.hovered,.next-radio-button>label:hover{border-color:#a0a2ad;background-color:#f2f3f7}.next-radio-button>label.checked{border-color:#5584ff}.next-radio-button>label.checked .next-radio-label{color:#5584ff}.next-radio-button>label.disabled{border-color:#e6e7eb;background-color:#f7f8fa}.next-radio-button>label.checked.disabled{border-color:#e6e7eb;background-color:#f2f3f7}.next-radio-button-medium>label{height:28px;line-height:28px}.next-radio-button-medium .next-radio-label{height:26px;line-height:26px;font-size:12px}.next-radio-label{font-size:12px}.next-checkbox-wrapper .next-checkbox-inner{border:1px solid #c4c6cf}.next-checkbox-wrapper .next-checkbox-inner>.next-icon{left:4px}.next-checkbox-wrapper .next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper .next-checkbox-inner>.next-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-checkbox-wrapper .next-checkbox-inner>.next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-checkbox-wrapper .next-checkbox-inner>.next-icon:before{width:16px;font-size:16px}}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner{background-color:#5584ff}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon:before,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon:before,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon:before{width:16px;font-size:16px}}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner{background-color:#5584ff}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon:before,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon:before,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon:before{width:16px;font-size:16px}}.next-checkbox-wrapper.focused>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper.hovered>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper:not(.disabled):hover>.next-checkbox>.next-checkbox-inner{border-color:#5584ff;background-color:#dee8ff}.next-checkbox-wrapper.checked:not(.disabled).hovered>.next-checkbox .next-checkbox-inner,.next-checkbox-wrapper.checked:not(.disabled):hover>.next-checkbox .next-checkbox-inner,.next-checkbox-wrapper.indeterminate:not(.disabled).hovered>.next-checkbox .next-checkbox-inner,.next-checkbox-wrapper.indeterminate:not(.disabled):hover>.next-checkbox .next-checkbox-inner{background-color:#3e71f7}.next-checkbox-wrapper.disabled.checked .next-checkbox-inner,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner,.next-checkbox-wrapper.disabled .next-checkbox-inner{border-color:#e6e7eb;background:#f7f8fa}.next-checkbox-wrapper.disabled.checked .next-checkbox-inner.hovered,.next-checkbox-wrapper.disabled.checked .next-checkbox-inner:hover,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner.hovered,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner:hover{border-color:#e6e7eb}.next-checkbox-wrapper.disabled.checked.focused .next-checkbox-inner{border-color:#e6e7eb;background:#f7f8fa}.next-checkbox-label{font-size:12px}.next-menu[dir=rtl] .next-menu-icon-selected.next-icon{margin-right:-16px}.next-menu[dir=rtl] .next-menu-icon-selected.next-icon .next-icon-remote,.next-menu[dir=rtl] .next-menu-icon-selected.next-icon:before{width:12px;font-size:12px}.next-menu{border:1px solid #dcdee3}.next-menu,.next-menu-item-helper{font-size:12px}.next-menu-item.next-selected .next-menu-icon-selected{color:#5584ff}.next-menu-item:not(.next-disabled).next-focused,.next-menu-item:not(.next-disabled).next-selected.next-focused,.next-menu-item:not(.next-disabled).next-selected.next-focused:hover,.next-menu-item:not(.next-disabled).next-selected:focus,.next-menu-item:not(.next-disabled).next-selected:focus:hover,.next-menu-item:not(.next-disabled).next-selected:hover,.next-menu-item:not(.next-disabled):hover{background-color:#f2f3f7}.next-menu-item:not(.next-disabled).next-focused .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected.next-focused .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected.next-focused:hover .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected:focus .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected:focus:hover .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected:hover .next-menu-icon-selected,.next-menu-item:not(.next-disabled):hover .next-menu-icon-selected{color:#5584ff}.next-menu-item-inner{font-size:12px}.next-menu-divider{border-bottom:1px solid #e6e7eb}.next-menu .next-menu-icon-selected.next-icon .next-icon-remote,.next-menu .next-menu-icon-selected.next-icon:before{width:12px;font-size:12px}.next-menu .next-menu-icon-arrow.next-icon .next-icon-remote,.next-menu .next-menu-icon-arrow.next-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-menu .next-menu-icon-arrow.next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-menu .next-menu-icon-arrow.next-icon:before{width:16px;font-size:16px}}.next-menu .next-menu-icon-arrow-down.next-open .next-icon-remote,.next-menu .next-menu-icon-arrow-down.next-open:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-menu .next-menu-icon-arrow-down.next-open{transform:scale(.5) rotate(180deg);margin-left:-4px;margin-right:-4px}.next-menu .next-menu-icon-arrow-down.next-open:before{width:16px;font-size:16px}}.next-menu .next-menu-icon-arrow-right.next-open .next-icon-remote,.next-menu .next-menu-icon-arrow-right.next-open:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-menu .next-menu-icon-arrow-right.next-open{transform:scale(.5) rotate(-90deg);margin-left:-4px;margin-right:-4px}.next-menu .next-menu-icon-arrow-right.next-open:before{width:16px;font-size:16px}}.next-input{border:1px solid #c4c6cf}.next-input.next-small{height:20px}.next-input.next-small input{height:18px;line-height:18px \0 }.next-input.next-small .next-input-text-field{height:18px;line-height:18px}.next-input.next-small .next-icon .next-icon-remote,.next-input.next-small .next-icon:before{width:12px;font-size:12px}.next-input.next-medium{height:28px}.next-input.next-medium .next-input-inner,.next-input.next-medium .next-input-label{font-size:12px}.next-input.next-medium input{height:26px;line-height:26px \0 ;font-size:12px}.next-input.next-medium input::placeholder{font-size:12px}.next-input.next-medium .next-input-text-field{font-size:12px;height:26px;line-height:26px}.next-input.next-medium .next-icon .next-icon-remote,.next-input.next-medium .next-icon:before{width:12px;font-size:12px}.next-input.next-large .next-icon .next-icon-remote,.next-input.next-large .next-icon:before{width:16px;font-size:16px}.next-input.next-input-textarea.next-small textarea,.next-input.next-input-textarea textarea{font-size:12px}.next-input.next-focus,.next-input:hover{border-color:#a0a2ad}.next-input.next-focus{border-color:#5584ff;box-shadow:0 0 0 2px rgba(85,132,255,.2)}.next-input.next-warning,.next-input.next-warning.next-focus,.next-input.next-warning:hover{border-color:#ff9300}.next-input.next-warning.next-focus{box-shadow:0 0 0 2px rgba(255,147,0,.2)}.next-input.next-error,.next-input.next-error.next-focus,.next-input.next-error:hover{border-color:#ff3000}.next-input.next-error.next-focus{box-shadow:0 0 0 2px rgba(255,48,0,.2)}.next-input-control .next-input-len.next-error{color:#ff3000}.next-input-control .next-input-len.next-warning,.next-input-control .next-input-warning-icon{color:#ff9300}.next-input-control .next-input-success-icon{color:#46bc15}.next-input-control .next-input-loading-icon{color:#4494f9}.next-input input::-moz-placeholder,.next-input textarea::-moz-placeholder{color:#999}.next-input input:-ms-input-placeholder,.next-input textarea:-ms-input-placeholder{color:#999}.next-input input::-webkit-input-placeholder,.next-input textarea::-webkit-input-placeholder{color:#999}.next-input.next-disabled,.next-input.next-disabled:hover{border-color:#e6e7eb;background-color:#f7f8fa}.next-input-group-text{background-color:#f2f3f7;border:1px solid #c4c6cf}.next-input-group-text.next-disabled,.next-input-group-text.next-disabled:hover{border-color:#e6e7eb;background-color:#f7f8fa}.next-form-preview.next-form-item.next-medium .next-form-item-label,.next-input-group-text.next-medium{font-size:12px}.next-form-responsive-grid.next-small .next-form-item.next-left .next-form-item-label{margin-top:4px;margin-bottom:4px}.next-form-responsive-grid.next-medium .next-form-item.next-left .next-form-item-label{margin-top:8px;margin-bottom:8px}.next-form-item.has-error>.next-form-item-control>.next-form-item-help{color:#ff3000}.next-form-item.has-warning>.next-form-item-control>.next-form-item-help{color:#ff9300}.next-form-item .next-form-item-label,.next-form-item .next-form-text-align,.next-form-item p{line-height:28px}.next-form-item .next-checkbox-group,.next-form-item .next-checkbox-wrapper,.next-form-item .next-radio-group,.next-form-item .next-radio-wrapper,.next-form-item .next-rating{line-height:24px}.next-form-item .next-form-preview{font-size:12px}.next-form-item .next-form-preview.next-input-textarea>p{font-size:12px;min-height:16.8px;margin-top:5.6px}.next-form-item .next-form-item-label{font-size:12px}.next-form-item.next-small .next-checkbox-group,.next-form-item.next-small .next-checkbox-wrapper,.next-form-item.next-small .next-form-item-label,.next-form-item.next-small .next-form-text-align,.next-form-item.next-small .next-radio-group,.next-form-item.next-small .next-radio-wrapper,.next-form-item.next-small .next-rating,.next-form-item.next-small p{line-height:20px}.next-form-item-label.next-left>label[required]:after,.next-form-item-label label[required]:before{color:#ff3000} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.filter-panel{text-align:right;padding:10px 0}.users-pagination{float:right;margin-top:20px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.header-container-primary{background:#252a2f}.header-container-normal{background-color:#fff;box-shadow:0 2px 10px 0 rgba(0,0,0,.08)}.header-container .header-body{width:100%;margin:0 auto;height:66px;line-height:66px}.header-container .header-body .logo{margin-left:40px;width:96px;vertical-align:sub}.header-container .header-body .header-menu{float:right}.header-container .header-body .header-menu .header-menu-toggle{display:none;width:19px;margin-right:40px;margin-top:18px;cursor:pointer}.header-container .header-body ul{padding:0;margin:0}.header-container .header-body li{display:inline-block;margin-right:40px}.header-container .header-body .menu-item{font-family:Avenir-Heavy;font-size:14px}.header-container .header-body .menu-item-primary a{color:#fff;opacity:.6;font-family:Avenir-Medium}.header-container .header-body .menu-item-primary-active a,.header-container .header-body .menu-item-primary:hover a{opacity:1}.header-container .header-body .menu-item-normal a{color:#333;opacity:.6;font-family:Avenir-Medium}.header-container .header-body .menu-item-normal-active a,.header-container .header-body .menu-item-normal:hover a{opacity:1}.header-container .header-body .language-switch{float:right;display:inline-block;box-sizing:border-box;width:24px;height:24px;line-height:20px;margin-top:21px;margin-right:40px;text-align:center;border-radius:2px;cursor:pointer;font-family:PingFangSC-Medium;font-size:14px;opacity:.6}.header-container .header-body .logout{float:right;color:#fff;opacity:.6;font-family:Avenir-Medium;margin-right:40px}.header-container .header-body .language-switch:hover{opacity:1}.header-container .header-body .language-switch-primary{border:1px solid #fff;color:#fff}.header-container .header-body .language-switch-normal{border:1px solid #333;color:#333}@media screen and (max-width:640px){.header-container .header-body .logo{margin-left:20px}.header-container .header-body .language-switch{margin-right:20px}.header-container .header-body .header-menu ul{display:none}.header-container .header-body .header-menu .header-menu-toggle{display:inline-block;margin-right:20px}.header-container .header-body .header-menu-open ul{background-color:#f8f8f8;display:inline-block;position:absolute;right:0;top:66px;z-index:100}.header-container .header-body .header-menu-open li{width:200px;display:list-item;padding-left:30px;list-style:none;line-height:40px;margin-right:0}.header-container .header-body .header-menu-open li a{color:#333;display:inline-block;width:100%}.header-container .header-body .header-menu-open li:hover{background:#2e3034}.header-container .header-body .header-menu-open li:hover a{color:#fff;opactiy:1}.header-container .header-body .header-menu-open .menu-item-normal-active,.header-container .header-body .header-menu-open .menu-item-primary-active{background:#2e3034}.header-container .header-body .header-menu-open .menu-item-normal-active a,.header-container .header-body .header-menu-open .menu-item-primary-active a{color:#fff;opactiy:1}}.bone{width:24px;height:2px;position:relative}.bone:before{left:0}.bone:after,.bone:before{position:absolute;content:"";width:6px;height:6px;border-radius:50%;top:-2px}.bone:after{right:0}.bone-dark,.bone-dark:after,.bone-dark:before{background-color:#1161f6}.bone-light,.bone-light:after,.bone-light:before{background-color:#fff;opacity:.8}.footer-container{background:#f8f8f8}.footer-container .footer-body{max-width:1280px;margin:0 auto;padding:40px 40px 0}@media screen and (max-width:640px){.footer-container .footer-body{padding-left:20px;padding-right:20px}}.footer-container .footer-body img{display:block;width:125px;height:26px;margin-bottom:40px}.footer-container .footer-body .cols-container .col{display:inline-block;box-sizing:border-box;vertical-align:top}.footer-container .footer-body .cols-container .col-12{width:50%;padding-right:125px}.footer-container .footer-body .cols-container .col-6{width:25%}.footer-container .footer-body .cols-container h3{font-family:Avenir-Heavy;font-size:18px;color:#333;line-height:18px;margin-bottom:20px}.footer-container .footer-body .cols-container p{font-family:Avenir-Medium;font-size:12px;color:#999;line-height:18px}.footer-container .footer-body .cols-container dl{font-family:Avenir-Heavy;line-height:18px}.footer-container .footer-body .cols-container dt{font-weight:700;font-size:18px;color:#333;margin-bottom:20px}.footer-container .footer-body .cols-container dd{padding:0;margin:0}.footer-container .footer-body .cols-container dd a{text-decoration:none;display:block;font-size:14px;color:#999;margin:10px 0}.footer-container .footer-body .cols-container dd a:hover{color:#2e3034}.footer-container .footer-body .copyright{margin-top:44px;border-top:1px solid #ccc;min-height:60px;line-height:20px;text-align:center;font-family:Avenir-Medium;font-size:12px;color:#999;display:flex;align-items:center}.footer-container .footer-body .copyright span{display:inline-block;margin:0 auto}@media screen and (max-width:640px){.footer-container .footer-body .cols-container .col{width:100%;text-align:center;padding:0}}.button{box-sizing:border-box;display:inline-block;height:48px;line-height:48px;min-width:140px;font-family:Avenir-Heavy;font-size:16px;color:#fff;text-align:center;border-radius:4px;text-decoration:none}.button-primary{background:#4190ff}.button-normal{background:transparent;border:1px solid #fff}@font-face{font-family:octicons-link;src:url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) format("woff")}.markdown-body{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;color:#24292e;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-size:16px;line-height:1.5;word-wrap:break-word}.markdown-body .pl-c{color:#6a737d}.markdown-body .pl-c1,.markdown-body .pl-s .pl-v{color:#005cc5}.markdown-body .pl-e,.markdown-body .pl-en{color:#6f42c1}.markdown-body .pl-s .pl-s1,.markdown-body .pl-smi{color:#24292e}.markdown-body .pl-ent{color:#22863a}.markdown-body .pl-k{color:#d73a49}.markdown-body .pl-pds,.markdown-body .pl-s,.markdown-body .pl-s .pl-pse .pl-s1,.markdown-body .pl-sr,.markdown-body .pl-sr .pl-cce,.markdown-body .pl-sr .pl-sra,.markdown-body .pl-sr .pl-sre{color:#032f62}.markdown-body .pl-smw,.markdown-body .pl-v{color:#e36209}.markdown-body .pl-bu{color:#b31d28}.markdown-body .pl-ii{color:#fafbfc;background-color:#b31d28}.markdown-body .pl-c2{color:#fafbfc;background-color:#d73a49}.markdown-body .pl-c2:before{content:"^M"}.markdown-body .pl-sr .pl-cce{font-weight:700;color:#22863a}.markdown-body .pl-ml{color:#735c0f}.markdown-body .pl-mh,.markdown-body .pl-mh .pl-en,.markdown-body .pl-ms{font-weight:700;color:#005cc5}.markdown-body .pl-mi{font-style:italic;color:#24292e}.markdown-body .pl-mb{font-weight:700;color:#24292e}.markdown-body .pl-md{color:#b31d28;background-color:#ffeef0}.markdown-body .pl-mi1{color:#22863a;background-color:#f0fff4}.markdown-body .pl-mc{color:#e36209;background-color:#ffebda}.markdown-body .pl-mi2{color:#f6f8fa;background-color:#005cc5}.markdown-body .pl-mdr{font-weight:700;color:#6f42c1}.markdown-body .pl-ba{color:#586069}.markdown-body .pl-sg{color:#959da5}.markdown-body .pl-corl{text-decoration:underline;color:#032f62}.markdown-body .octicon{display:inline-block;vertical-align:text-top;fill:currentColor}.markdown-body a{background-color:transparent}.markdown-body a:active,.markdown-body a:hover{outline-width:0}.markdown-body strong{font-weight:inherit;font-weight:bolder}.markdown-body h1{margin:.67em 0}.markdown-body img{border-style:none}.markdown-body code,.markdown-body kbd,.markdown-body pre{font-family:monospace,monospace;font-size:1em}.markdown-body hr{box-sizing:content-box;overflow:visible}.markdown-body input{font:inherit;margin:0;overflow:visible}.markdown-body [type=checkbox]{box-sizing:border-box;padding:0}.markdown-body *{box-sizing:border-box}.markdown-body input{font-family:inherit;font-size:inherit;line-height:inherit}.markdown-body a{color:#0366d6;text-decoration:none}.markdown-body a:hover{color:#0366d6;text-decoration:underline}.markdown-body strong{font-weight:600}.markdown-body hr{height:0;margin:15px 0;overflow:hidden;background:transparent;border-bottom:1px solid #dfe2e5}.markdown-body hr:after,.markdown-body hr:before{display:table;content:""}.markdown-body hr:after{clear:both}.markdown-body table{border-spacing:0;border-collapse:collapse}.markdown-body td,.markdown-body th{padding:0}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:0;margin-bottom:0}.markdown-body h1{font-size:32px;font-weight:600}.markdown-body h2{font-size:24px;font-weight:600}.markdown-body h3{font-size:20px;font-weight:600}.markdown-body h4{font-size:16px;font-weight:600}.markdown-body h5{font-size:14px;font-weight:600}.markdown-body h6{font-size:12px;font-weight:600}.markdown-body p{margin-top:0;margin-bottom:10px}.markdown-body blockquote{margin:0}.markdown-body ol,.markdown-body ul{padding-left:0;margin-top:0;margin-bottom:0}.markdown-body ol ol,.markdown-body ul ol{list-style-type:lower-roman}.markdown-body ol ol ol,.markdown-body ol ul ol,.markdown-body ul ol ol,.markdown-body ul ul ol{list-style-type:lower-alpha}.markdown-body dd{margin-left:0}.markdown-body code,.markdown-body pre{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px}.markdown-body pre{margin-top:0;margin-bottom:0}.markdown-body .octicon{vertical-align:text-bottom}.markdown-body .pl-0{padding-left:0!important}.markdown-body .pl-1{padding-left:4px!important}.markdown-body .pl-2{padding-left:8px!important}.markdown-body .pl-3{padding-left:16px!important}.markdown-body .pl-4{padding-left:24px!important}.markdown-body .pl-5{padding-left:32px!important}.markdown-body .pl-6{padding-left:40px!important}.markdown-body:after,.markdown-body:before{display:table;content:""}.markdown-body:after{clear:both}.markdown-body>:first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdown-body a:not([href]){color:inherit;text-decoration:none}.markdown-body .anchor{float:left;padding-right:4px;margin-left:-20px;line-height:1}.markdown-body .anchor:focus{outline:none}.markdown-body blockquote,.markdown-body dl,.markdown-body ol,.markdown-body p,.markdown-body pre,.markdown-body table,.markdown-body ul{margin-top:0;margin-bottom:16px}.markdown-body hr{height:.25em;padding:0;margin:24px 0;background-color:#e1e4e8;border:0}.markdown-body blockquote{padding:0 1em;color:#6a737d;border-left:.25em solid #dfe2e5}.markdown-body blockquote>:first-child{margin-top:0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body kbd{font-size:11px;border:1px solid #c6cbd1;border-bottom-color:#959da5;box-shadow:inset 0 -1px 0 #959da5}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{margin-top:24px;margin-bottom:16px;font-weight:600;line-height:1.25}.markdown-body h1 .octicon-link,.markdown-body h2 .octicon-link,.markdown-body h3 .octicon-link,.markdown-body h4 .octicon-link,.markdown-body h5 .octicon-link,.markdown-body h6 .octicon-link{color:#1b1f23;vertical-align:middle;visibility:hidden}.markdown-body h1:hover .anchor,.markdown-body h2:hover .anchor,.markdown-body h3:hover .anchor,.markdown-body h4:hover .anchor,.markdown-body h5:hover .anchor,.markdown-body h6:hover .anchor{text-decoration:none}.markdown-body h1:hover .anchor .octicon-link,.markdown-body h2:hover .anchor .octicon-link,.markdown-body h3:hover .anchor .octicon-link,.markdown-body h4:hover .anchor .octicon-link,.markdown-body h5:hover .anchor .octicon-link,.markdown-body h6:hover .anchor .octicon-link{visibility:visible}.markdown-body h1{font-size:2em}.markdown-body h1,.markdown-body h2{padding-bottom:.3em;border-bottom:1px solid #eaecef}.markdown-body h2{font-size:1.5em}.markdown-body h3{font-size:1.25em}.markdown-body h4{font-size:1em}.markdown-body h5{font-size:.875em}.markdown-body h6{font-size:.85em;color:#6a737d}.markdown-body ol,.markdown-body ul{padding-left:2em}.markdown-body ol ol,.markdown-body ol ul,.markdown-body ul ol,.markdown-body ul ul{margin-top:0;margin-bottom:0}.markdown-body li{word-wrap:break-all}.markdown-body li>p{margin-top:16px}.markdown-body li+li{margin-top:.25em}.markdown-body dl{padding:0}.markdown-body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:600}.markdown-body dl dd{padding:0 16px;margin-bottom:16px}.markdown-body table{display:block;width:100%;overflow:auto}.markdown-body table th{font-weight:600}.markdown-body table td,.markdown-body table th{padding:6px 13px;border:1px solid #dfe2e5}.markdown-body table tr{background-color:#fff;border-top:1px solid #c6cbd1}.markdown-body table tr:nth-child(2n){background-color:#f6f8fa}.markdown-body img{max-width:100%;box-sizing:content-box;background-color:#fff}.markdown-body img[align=right]{padding-left:20px}.markdown-body img[align=left]{padding-right:20px}.markdown-body code{padding:.2em .4em;margin:0;font-size:85%;background-color:rgba(27,31,35,.05);border-radius:3px}.markdown-body pre{word-wrap:normal}.markdown-body pre>code{padding:0;margin:0;font-size:100%;word-break:normal;white-space:pre;background:transparent;border:0}.markdown-body .highlight{margin-bottom:16px}.markdown-body .highlight pre{margin-bottom:0;word-break:normal}.markdown-body .highlight pre,.markdown-body pre{padding:16px;overflow:auto;font-size:85%;line-height:1.45;background-color:#f6f8fa;border-radius:3px}.markdown-body pre code{display:inline;max-width:auto;padding:0;margin:0;overflow:visible;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}.markdown-body .full-commit .btn-outline:not(:disabled):hover{color:#005cc5;border-color:#005cc5}.markdown-body kbd{display:inline-block;padding:3px 5px;font:11px SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;line-height:10px;color:#444d56;vertical-align:middle;background-color:#fafbfc;border:1px solid #d1d5da;border-bottom-color:#c6cbd1;border-radius:3px;box-shadow:inset 0 -1px 0 #c6cbd1}.markdown-body :checked+.radio-label{position:relative;z-index:1;border-color:#0366d6}.markdown-body .task-list-item{list-style-type:none}.markdown-body .task-list-item+.task-list-item{margin-top:3px}.markdown-body .task-list-item input{margin:0 .2em .25em -1.6em;vertical-align:middle}.markdown-body hr{border-bottom-color:#eee}.markdown-body pre code{display:block;overflow-x:auto;padding:.5em;background:#1e1e1e;color:#dcdcdc}.hljs-keyword,.hljs-link,.hljs-literal,.hljs-name,.hljs-symbol{color:#569cd6}.hljs-link{text-decoration:underline}.hljs-built_in,.hljs-type{color:#4ec9b0}.hljs-class,.hljs-number{color:#b8d7a3}.hljs-meta-string,.hljs-string{color:#d69d85}.hljs-regexp,.hljs-template-tag{color:#9a5334}.hljs-formula,.hljs-function,.hljs-params,.hljs-subst,.hljs-title{color:#dcdcdc}.hljs-comment,.hljs-quote{color:#57a64a;font-style:italic}.hljs-doctag{color:#608b4e}.hljs-meta,.hljs-meta-keyword,.hljs-tag{color:#9b9b9b}.hljs-template-variable,.hljs-variable{color:#bd63c5}.hljs-attr,.hljs-attribute,.hljs-builtin-name{color:#9cdcfe}.hljs-section{color:gold}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-bullet,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{color:#d7ba7d}.hljs-addition{background-color:#144212}.hljs-addition,.hljs-deletion{display:inline-block;width:100%}.hljs-deletion{background-color:#600}*{padding:0;margin:0}h1,h2,h3,h4,h5,h6{font-weight:400}.home-page .top-section{height:720px}.home-page .top-section .vertical-middle{width:100%}.home-page .top-section .product-logo{margin:0 auto}.home-page .top-section .button-area,.home-page .top-section .product-desc{text-align:center}.home-page .top-section .button-area .button:first-child{margin-right:20px}.home-page .top-section .version-note{text-align:center;margin:22px 0 10px}.home-page .top-section .version-note a{text-decoration:none;display:inline-block;font-family:Avenir-Heavy;font-size:14px;color:#fff;text-align:center;background:#46484b;border-radius:2px;line-height:24px;padding:0 6px;margin-right:10px}.home-page .top-section .release-date{font-family:Avenir-Medium;font-size:12px;color:#999;text-align:center}.home-page .function-section{max-width:832px;margin:0 auto;box-sizing:border-box;padding:82px 0}.home-page .function-section h3{font-family:Avenir-Heavy;font-size:36px;text-align:center;font-weight:400}.home-page .function-section .bone{margin:0 auto 45px}.home-page .function-section .func-item{margin-bottom:30px;position:relative}.home-page .function-section .func-item .col{display:inline-flex;align-items:center;vertical-align:middle;margin:0 auto;width:50%;max-width:750px;min-height:325px}.home-page .function-section .func-item .col img{width:325px}.home-page .function-section .func-item .col h4{font-weight:400;font-family:Avenir-Heavy;font-size:24px;color:#333;margin-bottom:20px}.home-page .function-section .func-item .col p{opacity:.8;font-family:Avenir-Medium;font-size:18px;color:#999;margin:0}.home-page .function-section .func-item .img{display:inline-block;text-align:center}@media screen and (max-width:830px){.home-page .function-section .func-item{text-align:center}.home-page .function-section .func-item .col{width:100%}.home-page .function-section .func-item .img{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);opacity:.1}}.home-page .feature-section{background:#2e3034}.home-page .feature-section .feature-section-body{max-width:1280px;margin:0 auto;position:relative;padding:80px 40px;color:#fff}.home-page .feature-section .feature-section-body h3{font-family:Avenir-Heavy;font-size:36px;text-align:center;margin:0;font-weight:400}.home-page .feature-section .feature-section-body .bone{margin:0 auto 45px}.home-page .feature-section .feature-section-body .feature-list{list-style:none;padding:0;margin:0}.home-page .feature-section .feature-section-body .feature-list .feature-list-item{vertical-align:top;display:inline-block;margin-bottom:48px;width:50%}.home-page .feature-section .feature-section-body .feature-list .feature-list-item ul{list-style:disc;padding-left:14px}.home-page .feature-section .feature-section-body .feature-list .feature-list-item ul li{font-family:Avenir-Medium;font-size:14px;color:#999}.home-page .feature-section .feature-section-body .feature-list .feature-list-item img{vertical-align:top;width:34px;margin-right:20px}.home-page .feature-section .feature-section-body .feature-list .feature-list-item div{display:inline-block;width:80%}.home-page .feature-section .feature-section-body .feature-list .feature-list-item div h4{font-family:Avenir-Heavy;font-size:20px;margin:5px 0 20px}.home-page .feature-section .feature-section-body .feature-list .feature-list-item div p{font-family:Avenir-Medium;font-size:14px;line-height:20px;color:#999}@media screen and (max-width:768px){.home-page .feature-section .feature-section-body .feature-list .feature-list-item{width:100%}}@media screen and (max-width:640px){.home-page .feature-section-body{padding-left:20px;padding-right:20px}}.product-nav-list li.selected a{background-color:#f4f6f8}.main-container{height:calc(100vh - 66px);background-color:#fff}.main-container .right-panel{background-color:#fff;width:calc(100% - 180px);padding:12px 32px;overflow:scroll}.main-container .nav-title{margin:0;text-align:center;font-size:14px;font-weight:700;height:60px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;border-bottom:var(--shell-brand-navigation-ver-divider-size,1px) var(--shell-brand-navigation-ver-divider-style,solid) var(--shell-brand-navigation-ver-divider-color,#eee);display:flex;justify-content:center;align-items:center}.main-container .nav-title span{margin-left:5px}.main-container .nav-mode{margin:0;text-align:center;font-size:12px;font-weight:700;height:45px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;border-bottom:var(--shell-brand-navigation-ver-divider-size,1px) var(--shell-brand-navigation-ver-divider-style,solid) var(--shell-brand-navigation-ver-divider-color,#eee);display:flex;justify-content:center;align-items:center}.main-container .nav-mode span{margin-left:5px}.main-container .nav-menu{padding:0;background:transparent;border:0;line-height:40px}.main-container .nav-menu .first-menu>.next-menu-item-inner,.main-container .nav-menu div.next-menu-item{color:#333}.main-container .nav-menu .next-menu-item-inner{height:40px;color:#666}.main-container .nav-menu .current-path{background-color:#f2f3f7}.main-container .go-back{text-align:center;color:#546478;font-size:20px;font-weight:700;padding:10px 0;margin-top:14px;cursor:pointer}.enable-dialog .next-dialog-body{padding-top:10px}.enable-dialog .next-dialog-close{display:none}.next-card{border:1px solid #dcdee3}.next-card-head{padding-left:16px;padding-right:16px}.next-card-head-show-bullet .next-card-title:before{background:#5584ff}.next-card-head-main{margin-top:8px;height:40px;line-height:40px}.next-card-extra{font-size:12px;color:#5584ff}.next-card-body{padding-bottom:12px;padding-left:16px;padding-right:16px}.next-card-show-divider>.next-card-head>.next-card-head-main{border-bottom:1px solid #e6e7eb}.next-card-show-divider>.next-card-body{padding-top:12px}.next-card-header{padding:0 16px;margin-bottom:12px;margin-top:12px}.next-card-actions{padding:12px 16px}.next-card-divider:before{border-bottom:1px solid #e6e7eb}.next-card-divider--inset{padding:0 16px}.next-card-content-container{margin-top:12px;padding-bottom:12px;padding-left:16px;padding-right:16px;font-size:12px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */@keyframes slashStar{0%{opacity:1}to{opacity:0}}.home-page .top-section{position:relative;height:100vh}.home-page .top-section .login-panel{position:absolute;right:40px;width:480px;height:540px;top:90px;border:0}.home-page .top-section .login-panel input,.home-page .top-section .login-panel input::-webkit-input-placeholder{font-size:16px}.home-page .top-section .login-panel .login-header{width:100%;line-height:45px;font-size:32px;margin-top:58px;text-align:center}.home-page .top-section .login-panel .internal-sys-tip{width:100%;line-height:25px;font-size:20px;margin-top:25px;text-align:center;font-weight:800;color:rgba(255,0,0,.8)}.home-page .top-section .login-panel .login-form{width:360px;margin:40px auto auto}.home-page .top-section .login-panel .login-form input{height:60px}.home-page .top-section .login-panel .login-form button{width:100%;height:60px;font-size:16px;background:#4190ff 100%;color:#fff;border:0}.home-page .top-section .animation{position:absolute;width:6px;height:6px;border-radius:50%;background-color:#1be1f6}.home-page .top-section .animation1{left:15%;top:70%;animation:slashStar 2s ease-in-out .3s infinite}.home-page .top-section .animation2{left:34%;top:35%;animation:slashStar 2s ease-in-out 1.2s infinite}.home-page .top-section .animation3{left:53%;top:20%;animation:slashStar 2s ease-in-out .5s infinite}.home-page .top-section .animation4{left:72%;top:64%;animation:slashStar 2s ease-in-out .8s infinite}.home-page .top-section .animation5{left:87%;top:30%;animation:slashStar 2s ease-in-out 1.5s infinite}.home-page .top-section .vertical-middle{position:absolute;left:0;top:50%;margin-top:-47px;transform:translateY(-50%)}.home-page .top-section .product-area{width:600px;margin-left:40px}.home-page .top-section .product-logo{display:block;width:257px;height:50px;margin:0}.home-page .top-section .product-desc{opacity:.8;font-family:Avenir-Medium;font-size:24px;color:#fff;max-width:780px;margin:12px auto 30px;text-align:left;line-height:30px}.next-table{border-top:1px solid #dcdee3;border-left:1px solid #dcdee3}.next-table th{background:#ebecf0;border-right:1px solid #dcdee3;border-bottom:1px solid #dcdee3}.next-table-header-resizable .next-table-resize-handler:hover:after{background:#5584ff}.next-table td{border-right:1px solid #dcdee3;border-bottom:1px solid #dcdee3}.next-table.zebra tr:nth-child(2n) td{background:#f7f8fa}.next-table.zebra .next-table-cell.hovered,.next-table.zebra .next-table-row.hovered td,.next-table.zebra .next-table-row.selected td{background:#f2f3f7}.next-table-empty{color:#a0a2ad}.next-table-expanded-row .next-table td,.next-table-expanded-row .next-table th{border-right:1px solid #dcdee3}.next-table-cell.hovered,.next-table-row.hovered,.next-table-row.selected{background:#f2f3f7}.next-table-body,.next-table-header{font-size:12px}.next-table-column-resize-proxy{border-left:2px solid #5584ff}.next-table-body{font-size:12px}.next-table-fixed{border-right:1px solid #dcdee3;border-bottom:1px solid #dcdee3}.next-table-fixed .next-table-header{background:#ebecf0}.next-table-group .next-table-body table,.next-table-group .next-table-header table{border-top:1px solid #dcdee3;border-left:1px solid #dcdee3}.next-table-group .next-table-group-footer td,.next-table-group .next-table-group-header td{background:#ebecf0}.next-table-filter .next-table-filter-active,.next-table-sort .current .next-icon,.next-tag-checkable.next-tag-level-secondary:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-secondary:not(.disabled):not([disabled]):hover{color:#5584ff}.next-tag-default.next-tag-level-primary{border-color:#ebecf0;background-color:#ebecf0}.next-tag-default.next-tag-level-primary:not(.disabled):not([disabled]).hover,.next-tag-default.next-tag-level-primary:not(.disabled):not([disabled]):hover{border-color:#e2e4e8;background-color:#e2e4e8}.disabled.next-tag-default.next-tag-level-primary,[disabled].next-tag-default.next-tag-level-primary{border-color:#f7f8fa;background-color:#f7f8fa}.next-tag-closable.next-tag-level-primary{border-color:#ebecf0;background-color:#ebecf0}.next-tag-closable.next-tag-level-primary:not(.disabled):not([disabled]).hover,.next-tag-closable.next-tag-level-primary:not(.disabled):not([disabled]):hover{border-color:#e2e4e8;background-color:#e2e4e8}.disabled.next-tag-closable.next-tag-level-primary,[disabled].next-tag-closable.next-tag-level-primary{border-color:#f7f8fa;background-color:#f7f8fa}.next-tag-checkable.next-tag-level-primary{border-color:#ebecf0;background-color:#ebecf0}.next-tag-checkable.next-tag-level-primary:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-primary:not(.disabled):not([disabled]):hover{border-color:#e2e4e8;background-color:#e2e4e8}.disabled.next-tag-checkable.next-tag-level-primary,[disabled].next-tag-checkable.next-tag-level-primary{border-color:#f7f8fa;background-color:#f7f8fa}.next-tag-checkable.next-tag-level-primary.checked{border-color:#5584ff;background-color:#5584ff}.next-tag-checkable.next-tag-level-primary.checked:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-primary.checked:not(.disabled):not([disabled]):hover{border-color:#3e71f7;background-color:#3e71f7}.disabled.next-tag-checkable.next-tag-level-primary.checked,[disabled].next-tag-checkable.next-tag-level-primary.checked{border-color:#f7f8fa;background-color:#f7f8fa}.next-tag-default.next-tag-level-normal{border-color:#c4c6cf}.next-tag-default.next-tag-level-normal:not(.disabled):not([disabled]).hover,.next-tag-default.next-tag-level-normal:not(.disabled):not([disabled]):hover{border-color:#a0a2ad}.disabled.next-tag-default.next-tag-level-normal,[disabled].next-tag-default.next-tag-level-normal{border-color:#e6e7eb;background-color:#f7f8fa}.next-tag-closable.next-tag-level-normal{border-color:#c4c6cf}.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]).hover,.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]):hover{border-color:#a0a2ad}.disabled.next-tag-closable.next-tag-level-normal,[disabled].next-tag-closable.next-tag-level-normal{border-color:#e6e7eb}.next-tag-checkable.next-tag-level-normal.checked{color:#5584ff;border-color:#5584ff}.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]):hover{color:#3e71f7;border-color:#3e71f7}.next-tag-checkable.next-tag-level-secondary.checked{color:#5584ff;border-color:#5584ff}.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]):hover{color:#3e71f7;border-color:#3e71f7}.next-tag-checkable.next-tag-level-secondary.checked:before{background-color:#5584ff}.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]).hover:before,.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]):hover:before{background-color:#3e71f7}.next-tag-checkable.next-tag-level-secondary.checked:disabled:before,[disabled].next-tag-checkable.next-tag-level-secondary.checked:before{background-color:#e6e7eb}.next-tag-checkable.next-tag-level-normal,.next-tag-checkable.next-tag-level-normal:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-normal:not(.disabled):not([disabled]):hover{border-color:#c4c6cf}.disabled.next-tag-checkable.next-tag-level-normal,[disabled].next-tag-checkable.next-tag-level-normal{border-color:#e6e7eb;background-color:#f7f8fa}.next-tag-checkable.next-tag-level-normal.checked:before{background-color:#5584ff}.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]).hover:before,.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]):hover:before{background-color:#3e71f7}.next-tag-checkable.next-tag-level-normal.checked:disabled:before,[disabled].next-tag-checkable.next-tag-level-normal.checked:before{background-color:#e6e7eb}.next-tag-closable.next-tag-level-normal:before{background-color:#c4c6cf}.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]).hover:before,.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]):hover:before{background-color:#a0a2ad}.next-tag-closable.next-tag-level-normal:disabled:before,[disabled].next-tag-closable.next-tag-level-normal:before{background-color:#e6e7eb}.next-tag-large.next-tag-closable>.next-tag-body{max-width:calc(100% - 44px)}.next-tag-large.next-tag-closable>.next-tag-close-btn .next-icon .next-icon-remote,.next-tag-large.next-tag-closable>.next-tag-close-btn .next-icon:before{width:12px;font-size:12px}.next-tag-medium{height:28px;line-height:26px}.next-tag-medium.next-tag-closable>.next-tag-body{max-width:calc(100% - 32px)}.next-tag-medium.next-tag-closable>.next-tag-close-btn .next-icon .next-icon-remote,.next-tag-medium.next-tag-closable>.next-tag-close-btn .next-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-tag-medium.next-tag-closable>.next-tag-close-btn .next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-tag-medium.next-tag-closable>.next-tag-close-btn .next-icon:before{width:16px;font-size:16px}}.next-tag-small{height:20px;line-height:18px}.next-tag-checkable.next-tag-level-secondary.disabled,.next-tag-checkable.next-tag-level-secondary[disabled]{border-color:#e6e7eb;background-color:#f7f8fa}.next-select-multiple .next-disabled .next-select-tag-compact{background:linear-gradient(90deg,transparent,#f7f8fa 10px)}.next-select-multiple.next-small .next-select-values,.next-select-tag.next-small .next-select-values{min-height:18px;padding-top:2px;padding-bottom:2px}.next-select-multiple.next-small .next-select-values-compact,.next-select-tag.next-small .next-select-values-compact{height:20px!important}.next-select-multiple.next-small .next-input-control,.next-select-multiple.next-small .next-input-inner,.next-select-multiple.next-small .next-input-label,.next-select-multiple.next-small .next-select-tag-compact,.next-select-tag.next-small .next-input-control,.next-select-tag.next-small .next-input-inner,.next-select-tag.next-small .next-input-label,.next-select-tag.next-small .next-select-tag-compact{line-height:18px}.next-select-multiple.next-medium .next-select-values,.next-select-tag.next-medium .next-select-values{min-height:26px;padding-top:3px;padding-bottom:3px}.next-select-multiple.next-medium .next-select-values-compact,.next-select-tag.next-medium .next-select-values-compact{height:28px!important}.next-select-multiple.next-medium .next-input-control,.next-select-multiple.next-medium .next-input-inner,.next-select-multiple.next-medium .next-input-label,.next-select-multiple.next-medium .next-select-tag-compact,.next-select-tag.next-medium .next-input-control,.next-select-tag.next-medium .next-input-inner,.next-select-tag.next-medium .next-input-label,.next-select-tag.next-medium .next-select-tag-compact{line-height:26px}.next-select-menu-wrapper{border:1px solid #dcdee3}.next-select-all{border-bottom:1px solid #dcdee3}.next-select-all:hover{color:#3e71f7}.next-select-all .next-menu-icon-selected.next-icon{color:#5584ff}.next-select-highlight{color:#5584ff;font-size:12px}.next-select-in-ie.next-select-trigger.next-select-single .next-input.next-small .next-select-values{line-height:20px}.next-select-in-ie.next-select-trigger.next-select-single .next-input.next-medium .next-select-values{line-height:28px}@media screen and (-webkit-min-device-pixel-ratio:0){.next-select-multiple .next-select-compact .next-select-tag-compact{background:linear-gradient(90deg,hsla(0,0%,100%,0),#fff 10px)}.next-select-multiple .next-disabled .next-select-tag-compact{background:linear-gradient(90deg,hsla(0,0%,100%,0),#f7f8fa 10px)}} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.naming-focus{color:#209bfa}.naming-focus,.naming-simple{padding-right:10px;border:none;font-size:14px}.naming-simple{color:#666} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.next-balloon{font-size:12px}.next-balloon-title.next-balloon-closable .next-balloon-close{transform:translateY(18px)}.next-balloon-primary{border-color:#4494f9;background-color:#e3f2fd}.next-balloon-primary .next-balloon-close{transform:translateY(16px);font-size:12px}.next-balloon-primary .next-balloon-close .next-icon{width:12px;height:12px}.next-balloon-primary .next-balloon-close .next-icon:before{width:12px;height:12px;font-size:12px}.next-balloon-primary:after{border:1px solid #4494f9;background-color:#e3f2fd}.next-balloon-normal{border-color:#dcdee3;box-shadow:0 2px 4px 0 rgba(0,0,0,.12)}.next-balloon-normal .next-balloon-close{transform:translateY(16px);font-size:12px}.next-balloon-normal .next-balloon-close .next-icon{width:12px;height:12px}.next-balloon-normal .next-balloon-close .next-icon:before{width:12px;height:12px;font-size:12px}.next-balloon-normal:after{border:1px solid #dcdee3}.next-balloon-tooltip{font-size:12px;color:#333}.next-balloon-tooltip,.next-balloon-tooltip .next-balloon-arrow .next-balloon-arrow-content{background-color:#f2f3f7;border:1px solid #dcdee3} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.new-config-form{margin-top:36px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.next-tabs-tab.active .next-tabs-tab-close{color:#5584ff}.next-tabs-btn-down.disabled,.next-tabs-btn-next.disabled,.next-tabs-btn-prev.disabled,.next-tabs-tab.disabled .next-tabs-tab-close{color:#dcdee3}.next-tabs.next-medium .next-tabs-tab-inner{font-size:12px;padding:12px 16px}.next-tabs-pure>.next-tabs-bar{border-bottom:1px solid #dcdee3}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab.active{color:#5584ff}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab.disabled{color:#dcdee3}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab:before{border-bottom:2px solid #5584ff}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab{background-color:#f2f3f7}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab:hover{background-color:#ebecf0}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.active{color:#5584ff}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.disabled{background:#f7f8fa}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.active .next-tabs-tab-close{color:#5584ff}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.disabled .next-tabs-tab-close{color:#dcdee3}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab{border:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab:hover{border-color:#c4c6cf}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab.active{border-color:#dcdee3 #dcdee3 #fff}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab:before{border-top:2px solid #5584ff}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar:before{border-bottom:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab{border:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab:hover{border-color:#c4c6cf}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab.active{border-color:#fff #dcdee3 #dcdee3}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab:before{border-bottom:2px solid #5584ff}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-content{border-bottom:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab{border:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab:hover{border-color:#c4c6cf}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab.active{border-color:#dcdee3 #fff #dcdee3 #dcdee3}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab:before{border-left:2px solid #5584ff}.next-tabs-wrapped.next-tabs-left>.next-tabs-content{border-left:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab{border:1px solid #dcdee3}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab:hover{border-color:#c4c6cf}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab.active{border-color:#dcdee3 #dcdee3 #dcdee3 #fff}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab:before{border-right:2px solid #5584ff}.next-tabs-wrapped.next-tabs-right>.next-tabs-content{border-right:1px solid #dcdee3}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab{border:1px solid #c4c6cf;background-color:#f2f3f7}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab:last-child{border-right:1px solid #c4c6cf}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.active{border-color:#5584ff}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.disabled{border-color:#e6e7eb}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab:hover{border-color:#c4c6cf;background-color:#ebecf0}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.active{background-color:#5584ff}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.disabled{background:#f7f8fa}.next-tabs-text>.next-tabs-bar .next-tabs-tab.active{color:#5584ff}.next-tabs-text>.next-tabs-bar .next-tabs-tab:not(:last-child):after{background-color:#dcdee3}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab{border:1px solid #c4c6cf}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab:last-child{border-left:1px solid #c4c6cf}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab.active{border-color:#5584ff} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.button-list{text-align:right}.button-list button{margin-left:1em;font-size:14px}.editor-full-screen{width:100%;height:100%;position:fixed;top:0;left:0;z-index:100}.editor-normal{clear:both}.more-item.hide{display:none} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.config-editor{padding:10px}.config-editor .func-title{overflow:hidden;height:50px;width:100%;font-weight:500;margin-bottom:9px;font-size:18px;line-height:36px;color:#73777a}.config-editor .form{display:table}.config-editor .form .next-form-item{display:table-row}.config-editor .form .next-form-item .next-form-item-label{white-space:nowrap;word-break:keep-all}.config-editor .form .next-form-item .next-form-item-control,.config-editor .form .next-form-item .next-select{width:100%}.config-editor .form .next-form-item .next-form-item-control,.config-editor .form .next-form-item .next-form-item-label{display:table-cell}.config-editor .form .next-form-item-control{padding-bottom:12px}.config-editor .form .next-checkbox-label{color:#73777a;font-weight:400}.config-editor .form .next-radio-label{color:#73777a}.config-editor .form .switch{color:#33cde5;cursor:pointer;user-select:none}.config-editor .form .help-label>*{display:inline-block}.config-editor .form .help-label>i{color:#1dc11d;margin:0 .25em}.config-editor .button-list{text-align:right}.config-editor .button-list button{margin-left:1em;font-size:14px}.config-editor .editor-full-screen{width:100%;height:100%;position:fixed;top:0;left:0;z-index:100}.config-editor .editor-normal{clear:both} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.next-pagination[dir=rtl] .next-pagination-size-selector-btn.next-btn-text+.next-pagination-size-selector-btn{border-right:1px solid #dcdee3}.next-pagination[dir=rtl].next-small .next-pagination-total{line-height:20px}.next-pagination[dir=rtl].next-small .next-pagination-ellipsis,.next-pagination[dir=rtl].next-small .next-pagination-size-selector-title{height:20px;line-height:20px}.next-pagination[dir=rtl].next-medium .next-pagination-total{line-height:28px}.next-pagination[dir=rtl].next-medium .next-pagination-ellipsis{height:28px;line-height:28px}.next-pagination[dir=rtl].next-medium .next-pagination-display,.next-pagination[dir=rtl].next-medium .next-pagination-display em,.next-pagination[dir=rtl].next-medium .next-pagination-jump-text{font-size:12px}.next-pagination[dir=rtl].next-medium .next-pagination-size-selector-title{height:28px;line-height:28px;font-size:12px}.next-pagination .next-pagination-item:not([disabled]){border-color:#c4c6cf}.next-pagination .next-pagination-item.next-current{border-color:#5584ff;background:#5584ff}.next-pagination .next-pagination-item.next-current:focus,.next-pagination .next-pagination-item.next-current:hover{border-color:transparent;background:#3e71f7;color:#fff}.next-pagination-display em,.next-pagination-size-selector-btn.next-btn-text.next-current{color:#5584ff}.next-pagination-size-selector-btn.next-btn-text+.next-pagination-size-selector-btn{border-left:1px solid #dcdee3}.next-pagination.next-small .next-pagination-total{line-height:20px}.next-pagination.next-small .next-pagination-ellipsis,.next-pagination.next-small .next-pagination-size-selector-title{height:20px;line-height:20px}.next-pagination.next-small.next-no-border .next-pagination-item.next-next:not([disabled]):hover i,.next-pagination.next-small.next-no-border .next-pagination-item.next-prev:not([disabled]):hover i{color:#5584ff}.next-pagination.next-medium .next-pagination-total{line-height:28px}.next-pagination.next-medium .next-pagination-ellipsis{height:28px;line-height:28px}.next-pagination.next-medium .next-pagination-display,.next-pagination.next-medium .next-pagination-display em,.next-pagination.next-medium .next-pagination-jump-text{font-size:12px}.next-pagination.next-medium .next-pagination-size-selector-title{height:28px;line-height:28px;font-size:12px}.next-pagination.next-large.next-no-border .next-pagination-item.next-next:not([disabled]):hover i,.next-pagination.next-large.next-no-border .next-pagination-item.next-prev:not([disabled]):hover i,.next-pagination.next-medium.next-no-border .next-pagination-item.next-next:not([disabled]):hover i,.next-pagination.next-medium.next-no-border .next-pagination-item.next-prev:not([disabled]):hover i{color:#5584ff} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.query_result_wrapper{font-size:16px;margin-bottom:16px;font-family:Helvetica Neue,Luxi Sans,DejaVu Sans,Tahoma,Hiragino Sans GB,STHeiti,Microsoft YaHei} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.next-switch-loading .next-icon-loading{color:#5584ff}.next-switch-medium{width:56px;border-radius:20px}.next-switch-medium.next-switch-auto-width{min-width:56px}.next-switch-medium>.next-switch-btn{border-radius:20px}.next-switch-medium>.next-switch-children{font-size:12px}.next-switch-small,.next-switch-small>.next-switch-btn{border-radius:20px}.next-switch-on{background-color:#5584ff}.next-switch-on.hover,.next-switch-on:focus,.next-switch-on:hover{background-color:#3e71f7}.next-switch-on[disabled]{background-color:#ebecf0}.next-switch-on[disabled] .next-switch-btn{background-color:#f7f8fa}.next-switch-off,.next-switch-off.hover,.next-switch-off:focus,.next-switch-off:hover{background-color:#ebecf0;border-color:#ebecf0}.next-switch-off[disabled]{background-color:#ebecf0}.next-switch-off[disabled] .next-switch-btn{background-color:#f7f8fa}.next-switch-off[disabled]>.next-switch-children{color:#c4c6cf}.next-progress-line-underlay{background:#ebecf0}.next-progress-line-overlay-normal{background:#5584ff}.next-progress-line-overlay-success{background:#46bc15}.next-progress-line-overlay-error,.next-progress-line-overlay-started{background:#ff3000}.next-progress-line-overlay-middle{background:#ff9300}.next-progress-line-overlay-finishing{background:#46bc15}.next-progress-line.next-large .next-progress-line-overlay,.next-progress-line.next-large .next-progress-line-underlay,.next-progress-line.next-medium .next-progress-line-overlay,.next-progress-line.next-medium .next-progress-line-underlay,.next-progress-line.next-small .next-progress-line-overlay,.next-progress-line.next-small .next-progress-line-underlay{border-radius:20px}.next-progress-line.next-large .next-progress-line-text{font-size:12px}.next-progress-line-show-border .next-progress-line-underlay{border:1px solid #dcdee3}.next-progress-line-show-border.next-large .next-progress-line-overlay,.next-progress-line-show-border.next-large .next-progress-line-underlay,.next-progress-line-show-border.next-medium .next-progress-line-overlay,.next-progress-line-show-border.next-medium .next-progress-line-underlay,.next-progress-line-show-border.next-small .next-progress-line-overlay,.next-progress-line-show-border.next-small .next-progress-line-underlay{border-radius:20px}.next-progress-line-show-border.next-large .next-progress-line-text{font-size:12px}.next-progress-circle-underlay{stroke:#ebecf0}.next-progress-circle-overlay-normal{stroke:#5584ff}.next-progress-circle-overlay-success{stroke:#46bc15}.next-progress-circle-overlay-error,.next-progress-circle-overlay-started{stroke:#ff3000}.next-progress-circle-overlay-middle{stroke:#ff9300}.next-progress-circle-overlay-finishing{stroke:#46bc15}.next-upload-list[dir=rtl].next-upload-list-text .next-upload-list-item{padding:4px 8px 4px 36px}.next-upload-list[dir=rtl].next-upload-list-image .next-upload-list-item-progress{margin-left:20px}.next-upload.next-disabled,.next-upload.next-disabled .next-upload-inner *{border-color:#e6e7eb!important}.next-upload-list-text .next-upload-list-item{background-color:#f2f3f7;padding:4px 36px 4px 8px;font-size:12px}.next-upload-list-text .next-upload-list-item .next-icon-close .next-icon-remote,.next-upload-list-text .next-upload-list-item .next-icon-close:before{width:12px;font-size:12px}.next-upload-list-text .next-upload-list-item:hover{background-color:#f2f3f7}.next-upload-list-text .next-upload-list-item-done:hover .next-upload-list-item-name,.next-upload-list-text .next-upload-list-item-done:hover .next-upload-list-item-size{color:#5584ff}.next-upload-list-text .next-upload-list-item-error-msg{color:#ff3000}.next-upload-list-image .next-upload-list-item{border:1px solid #dcdee3;font-size:12px}.next-upload-list-image .next-upload-list-item .next-icon-close .next-icon-remote,.next-upload-list-image .next-upload-list-item .next-icon-close:before{width:12px;font-size:12px}.next-upload-list-image .next-upload-list-item:hover{border-color:#5584ff}.next-upload-list-image .next-upload-list-item-name{margin-right:20px}.next-upload-list-image .next-upload-list-item-done:hover .next-upload-list-item-name,.next-upload-list-image .next-upload-list-item-done:hover .next-upload-list-item-size{color:#5584ff}.next-upload-list-image .next-upload-list-item-thumbnail{border:1px solid #dcdee3;background-color:#f2f3f7}.next-upload-list-image .next-upload-list-item-error{border-color:#ff3000!important}.next-upload-list-image .next-upload-list-item-uploading .next-upload-list-item-progress{margin-right:20px}.next-upload-list-image .next-upload-list-item-error-with-msg .next-upload-list-item-error-msg{margin-right:20px;color:#ff3000}.next-upload-list-card .next-upload-list-item-wrapper{border:1px solid #c4c6cf}.next-upload-list-card .next-upload-list-item-uploading .next-upload-list-item-wrapper{background-color:#f7f8fa}.next-upload-list-card .next-upload-list-item-error .next-upload-list-item-wrapper{border-color:#ff3000}.next-upload-card{border:1px dashed #c4c6cf}.next-upload-card .next-icon{color:#c4c6cf}.next-upload-card .next-upload-text{font-size:12px}.next-upload-card:hover{border-color:#5584ff}.next-upload-card:hover .next-icon,.next-upload-card:hover .next-upload-text{color:#5584ff}.next-upload-dragable .next-upload-drag{border:1px dashed #c4c6cf}.next-upload-dragable .next-upload-drag-over{border-color:#5584ff}.next-collapse[dir=rtl] .next-collapse-panel-title{padding:8px 28px 8px 0}.next-collapse[dir=rtl] .next-collapse-panel-icon .next-icon-remote,.next-collapse[dir=rtl] .next-collapse-panel-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-collapse[dir=rtl] .next-collapse-panel-icon{transform:scale(.5) rotate(180deg);margin-left:-4px;margin-right:-4px}.next-collapse[dir=rtl] .next-collapse-panel-icon:before{width:16px;font-size:16px}}.next-collapse{border:1px solid #dcdee3}.next-collapse-panel:not(:first-child){border-top:1px solid #dcdee3}.next-collapse .next-collapse-panel-icon .next-icon-remote,.next-collapse .next-collapse-panel-icon:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-collapse .next-collapse-panel-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-collapse .next-collapse-panel-icon:before{width:16px;font-size:16px}}.next-collapse-panel-title{background:#f2f3f7;padding:8px 0 8px 28px}.next-collapse-panel-title:hover{background:#ebecf0}.next-collapse-panel-content{font-size:12px}.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded .next-icon-remote,.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded:before{width:8px;font-size:8px}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded{transform:scale(.5) rotate(90deg);margin-left:-4px;margin-right:-4px}.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded:before{width:16px;font-size:16px}}.next-collapse-disabled,.next-collapse-panel-disabled:not(:first-child){border-color:#e6e7eb}.next-collapse-panel-disabled:hover,.next-collapse-panel-disabled>.next-collapse-panel-title{background:#f2f3f7}.next-menu-btn.next-btn-secondary.next-btn-text:hover .next-menu-btn-arrow,.next-menu-btn.next-btn-secondary .next-menu-btn-arrow,.next-menu-btn.next-btn-text.next-btn-normal:hover .next-menu-btn-arrow,.next-menu-btn.next-btn-text.next-btn-primary .next-menu-btn-arrow{color:#5584ff}.next-menu-btn.next-btn-text.next-btn-primary:hover .next-menu-btn-arrow{color:#3e71f7}.next-search-simple[dir=rtl].next-normal .next-search-left .next-search-left-addon{border-left:1px solid #c4c6cf}.next-search-simple[dir=rtl].next-dark .next-search-left{border-color:#c4c6cf}.next-search-simple[dir=rtl].next-dark .next-search-left .next-search-left-addon{border-right:1px solid #c4c6cf}.next-search-simple[dir=rtl].next-dark:hover .next-search-left{border-color:#c4c6cf}.next-search-simple[dir=rtl].next-dark .next-search-icon{color:#999}.next-search-simple[dir=rtl].next-dark .next-search-icon:hover{color:#666}.next-search-normal[dir=rtl].next-primary .next-input{border-top-right-radius:1px;border-bottom-right-radius:1px}.next-search-normal[dir=rtl].next-primary .next-search-left .next-search-left-addon{border-left:1px solid #e6e7eb}.next-search-normal[dir=rtl].next-secondary .next-input{border-top-right-radius:1px;border-bottom-right-radius:1px}.next-search-normal[dir=rtl].next-secondary .next-search-left .next-search-left-addon{border-left:1px solid #e6e7eb}.next-search-normal[dir=rtl].next-normal .next-input{border-top-right-radius:1px;border-bottom-right-radius:1px}.next-search-normal[dir=rtl].next-normal .next-search-left .next-search-left-addon{border-left:1px solid #e6e7eb}.next-search-normal[dir=rtl].next-dark .next-search-left .next-search-left-addon{border-left:1px solid #5584ff}.next-search.next-search-focus.next-search-normal.next-primary .next-search-left,.next-search.next-search-focus.next-search-normal.next-secondary .next-search-left{border-color:#5584ff}.next-search.next-search-focus.next-search-normal.next-normal .next-search-left{border-color:#a0a2ad}.next-search.next-search-focus.next-search-normal.next-dark .next-search-left{border-color:#5584ff}.next-search.next-search-focus.next-search-simple.next-dark .next-search-left{border-color:#c4c6cf}.next-search.next-search-focus.next-search-simple.next-normal .next-search-left{border-color:#a0a2ad}.next-search-normal.next-primary .next-search-left{border-color:#5584ff}.next-search-normal.next-primary .next-search-left .next-search-left-addon{border-right:1px solid #e6e7eb}.next-search-normal.next-primary:hover .next-btn,.next-search-normal.next-primary:hover .next-search-left{border-color:#5584ff}.next-search-normal.next-primary .next-search-btn{background:#5584ff;border-color:#5584ff}.next-search-normal.next-primary .next-search-btn:hover{background:#3e71f7;border-color:#5584ff}.next-search-normal.next-primary.next-large .next-search-btn,.next-search-normal.next-primary.next-large .next-search-left{border-width:2px;height:60px}.next-search-normal.next-primary.next-large .next-search-input{height:56px}.next-search-normal.next-primary.next-large .next-search-input input{height:56px;line-height:56px \0 }.next-search-normal.next-primary.next-large .next-select{height:56px}.next-search-normal.next-primary.next-medium .next-search-btn,.next-search-normal.next-primary.next-medium .next-search-left{border-width:2px;height:40px}.next-search-normal.next-primary.next-medium .next-search-input{height:36px}.next-search-normal.next-primary.next-medium .next-search-input input{height:36px;line-height:36px \0 }.next-search-normal.next-primary.next-medium .next-select{height:36px}.next-search-normal.next-primary.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-primary.next-medium .next-search-btn .next-icon:before{width:16px;font-size:16px}.next-search-normal.next-primary .next-input{border-top-left-radius:1px;border-bottom-left-radius:1px}.next-search-normal.next-secondary .next-search-left{border-color:#c4c6cf}.next-search-normal.next-secondary .next-search-left .next-search-left-addon{border-right:1px solid #e6e7eb}.next-search-normal.next-secondary:hover .next-btn,.next-search-normal.next-secondary:hover .next-search-left{border-color:#5584ff}.next-search-normal.next-secondary .next-search-btn{background:#5584ff;border-color:#5584ff}.next-search-normal.next-secondary .next-search-btn:hover{background:#3e71f7;border-color:#5584ff}.next-search-normal.next-secondary.next-large .next-search-btn,.next-search-normal.next-secondary.next-large .next-search-left{height:60px}.next-search-normal.next-secondary.next-large .next-search-input{height:58px}.next-search-normal.next-secondary.next-large .next-search-input input{height:58px;line-height:58px \0 }.next-search-normal.next-secondary.next-large .next-select{height:58px}.next-search-normal.next-secondary.next-medium .next-search-btn,.next-search-normal.next-secondary.next-medium .next-search-left{height:40px}.next-search-normal.next-secondary.next-medium .next-search-input{height:38px}.next-search-normal.next-secondary.next-medium .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-secondary.next-medium .next-select{height:38px}.next-search-normal.next-secondary.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-secondary.next-medium .next-search-btn .next-icon:before{width:16px;font-size:16px}.next-search-normal.next-normal .next-search-left{border-color:#c4c6cf}.next-search-normal.next-normal .next-search-left .next-search-left-addon{border-right:1px solid #e6e7eb}.next-search-normal.next-normal:hover .next-btn,.next-search-normal.next-normal:hover .next-search-left{border-color:#a0a2ad}.next-search-normal.next-normal .next-search-btn{background:#f7f8fa;border-color:#c4c6cf}.next-search-normal.next-normal .next-search-btn:hover{background:#ebecf0;border-color:#a0a2ad}.next-search-normal.next-normal.next-large .next-search-btn,.next-search-normal.next-normal.next-large .next-search-left{height:60px}.next-search-normal.next-normal.next-large .next-search-input{height:58px}.next-search-normal.next-normal.next-large .next-search-input input{height:58px;line-height:58px \0 }.next-search-normal.next-normal.next-large .next-select{height:58px}.next-search-normal.next-normal.next-medium .next-search-btn,.next-search-normal.next-normal.next-medium .next-search-left{height:40px}.next-search-normal.next-normal.next-medium .next-search-input{height:38px}.next-search-normal.next-normal.next-medium .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-normal.next-medium .next-select{height:38px}.next-search-normal.next-normal.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-normal.next-medium .next-search-btn .next-icon:before{width:16px;font-size:16px}.next-search-normal.next-dark .next-search-left{border-color:#5584ff}.next-search-normal.next-dark .next-search-left .next-search-left-addon{border-right:1px solid #5584ff}.next-search-normal.next-dark:hover .next-btn,.next-search-normal.next-dark:hover .next-search-left{border-color:#5584ff}.next-search-normal.next-dark .next-search-btn{background:#5584ff;border-color:#5584ff}.next-search-normal.next-dark .next-search-btn:hover{background:#3e71f7;border-color:#5584ff}.next-search-normal.next-dark.next-large .next-search-btn,.next-search-normal.next-dark.next-large .next-search-left{height:60px}.next-search-normal.next-dark.next-large .next-search-input{height:58px}.next-search-normal.next-dark.next-large .next-search-input input{height:58px;line-height:58px \0 }.next-search-normal.next-dark.next-large .next-select{height:58px}.next-search-normal.next-dark.next-medium .next-search-btn,.next-search-normal.next-dark.next-medium .next-search-left{height:40px}.next-search-normal.next-dark.next-medium .next-search-input{height:38px}.next-search-normal.next-dark.next-medium .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-dark.next-medium .next-select{height:38px}.next-search-normal.next-dark.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-dark.next-medium .next-search-btn .next-icon:before{width:16px;font-size:16px}.next-search-simple.next-normal .next-search-left{border-color:#c4c6cf}.next-search-simple.next-normal .next-search-left .next-search-left-addon{border-right:1px solid #c4c6cf}.next-search-simple.next-normal:hover .next-search-left{border-color:#a0a2ad}.next-search-simple.next-dark .next-search-left{border-color:#c4c6cf}.next-search-simple.next-dark .next-search-left .next-search-left-addon{border-right:1px solid #c4c6cf}.next-search-simple.next-dark:hover .next-search-left{border-color:#c4c6cf}.next-search-simple.next-dark .next-search-icon{color:#999}.next-search-simple.next-dark .next-search-icon:hover{color:#666}.next-search-simple.next-dark.next-medium .next-search-icon .next-icon-remote,.next-search-simple.next-dark.next-medium .next-search-icon:before{width:12px;font-size:12px}.next-search-simple .next-select.next-medium{height:26px}.next-transfer-panel{border:1px solid #dcdee3}.next-transfer-panel-header{border-bottom:1px solid #dcdee3;background-color:#f7f8fa;font-size:12px}.next-transfer-panel-item:not(.next-disabled).next-simple:hover{color:#5584ff}.next-transfer-panel-item.next-insert-before:before{border-top:1px solid #5584ff}.next-transfer-panel-item.next-insert-after:after{border-bottom:1px solid #5584ff}.next-transfer-panel-footer{border-top:1px solid #dcdee3}.next-transfer-panel-count{font-size:12px}.next-transfer-panel-move-all{font-size:12px;color:#5584ff}.next-transfer-move.next-icon{color:#c4c6cf} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.next-slick-arrow.inner.disabled{background:#f7f8fa}.next-slick-dots-item.active button{background:#5584ff} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.next-pagination-size-selector{position:static!important}.configuration-table{margin-bottom:20px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.service-management{padding-top:12px}.service-management .page-title{height:30px;width:100%;line-height:30px;margin:0 0 20px}.service-management .title-item{font-size:14px;color:#000;margin-right:8px}.service-management .next-switch-off{background-color:#f2f3f7;border-color:#c4c6cf} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.service-detail .header-btn{float:right;margin-left:20px}.service-detail .edit-btn{margin-right:10px}.service-detail .next-form-item{margin-bottom:10px}.service-detail .loading{position:relative;width:100%}.service-detail .pagination{float:right;margin-top:15px}.service-detail .cluster-card{margin-bottom:30px}.cluster-edit-dialog .next-form-item,.instance-edit-dialog .next-form-item,.service-detail-edit-dialog .next-form-item,.service-detail .inner-card{margin-bottom:10px}.cluster-edit-dialog .next-col-fixed-12,.instance-edit-dialog .next-col-fixed-12,.service-detail-edit-dialog .next-col-fixed-12{flex:1}.cluster-edit-dialog .next-switch-off,.instance-edit-dialog .next-switch-off,.service-detail-edit-dialog .next-switch-off{background-color:#f2f3f7;border-color:#c4c6cf}.cluster-edit-dialog .in-select,.cluster-edit-dialog .in-text,.instance-edit-dialog .in-select,.instance-edit-dialog .in-text,.service-detail-edit-dialog .in-select,.service-detail-edit-dialog .in-text{width:120px}.service-detail-edit-dialog{width:600px}.full-width{width:100%} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.subscriber-list{padding-top:12px}.subscriber-list .page-title{height:30px;width:100%;line-height:30px;margin:0 0 20px}.subscriber-list .title-item{font-size:14px;color:#000;margin-right:8px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.cluster-management .page-title{height:30px;width:100%;line-height:30px;margin:0 0 20px;padding:0 0 0 10px;border-left:3px solid #09c;color:#ccc}.cluster-management .title-item{font-size:14px;color:#000;margin-right:8px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*! + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.setting-box{margin-top:15px;padding:20px;background-color:#fff;border:1px solid #f6f7fb;border-radius:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1)}.text-box{width:100%;flex-wrap:wrap;display:flex}.setting-checkbox{flex:0 0 50%;height:100px;box-sizing:border-box}.setting-span{font-size:18px;font-weight:400;margin-bottom:15px} +/*! + * Copyright 1999-2018 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *//*! + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */.dark{filter:grayscale(.25)}.dark .login-header{color:#fff}.dark .next-menu-item:not(.next-disabled).next-focused,.dark .next-shell-navigation.next-shell-mini.next-shell-aside{background-color:#2d2d2d!important;color:#fff!important;border-color:#3e3e3e}.dark .next-menu-item{color:#fff!important}.dark .next-nav-embeddable.next-normal .next-menu-sub-menu .next-menu-item,.dark .next-nav-embeddable.next-normal .next-nav-item.next-menu-item,.dark .next-nav-embeddable.next-primary .next-menu-sub-menu .next-menu-item,.dark .next-nav-embeddable.next-primary .next-nav-item.next-menu-item,.dark .next-nav-embeddable.next-secondary .next-menu-sub-menu .next-menu-item,.dark .next-nav-embeddable.next-secondary .next-nav-item.next-menu-item{background-color:#161616!important;color:#929299!important}.dark .next-menu-item:not(.next-disabled):hover{background-color:#424346!important}.dark .next-menu-item.next-selected,.dark .next-menu.next-normal .next-menu-item.next-selected,.dark .next-nav.next-normal .next-menu-sub-menu .next-menu-item.next-focused,.dark .next-nav.next-normal .next-menu-sub-menu .next-menu-item:hover{background-color:#424346!important;color:#209bfa!important}.dark .main-container .right-panel,.dark .next-shell-brand .next-shell-main{background-color:#161616!important}.dark .main-container .right-panel::-webkit-scrollbar,.dark .main-container .right-panel::-webkit-scrollbar-corner,.dark .main-container .right-panel::-webkit-scrollbar-track{background-color:#161616!important}.dark .page-title{color:#fff}.dark .nav-mode,.dark .nav-title{border-color:#1c1d1f}.dark .next-message.next-message-notice.next-inline{background-color:#161616;border-color:#929299}.dark .next-message.next-message-notice.next-inline .next-message-content{color:#c9c9cc}.dark .namespacewrapper{background-color:#303030!important}.dark .namespacewrapper .naming-simple{color:#c9c9cc}.dark .next-table{border-color:#3e3e3e!important}.dark .next-table table{background-color:#303030!important}.dark .query_result_wrapper{color:#fff}.dark .next-table-header th{background-color:#4a4a4a!important;color:#fff}.dark .next-table-row{background-color:#303030!important;color:#c9c9cc}.dark .next-table-sort .next-icon{color:#fff}.dark .next-table td,.dark .next-table th{border-color:#3e3e3e!important}.dark .next-table-row.selected{background:#424346!important;color:#c9c9cc}.dark .next-table-row.hovered{background:#4a4a4a!important;color:#fff}.dark .next-table-header-fixer{background:#4a4a4a!important}.dark .next-table-cell-wrapper a{color:#209bfa}.dark form label{color:#c9c9cc!important}.dark .naming-copy{background:#303030!important;color:#fff!important}.dark .next-menu.next-ver{background-color:#2d2d2d;border-color:#424346}.dark .next-overlay-wrapper .opened .next-menu-item:not(.next-disabled):hover{background-color:#fff}.dark .next-dialog-header,.dark .next-message.next-large.next-title-content .next-message-title{color:#fff}.dark .next-overlay-wrapper .next-overlay-inner{border-color:#1c1d1f;background-color:#161616}.dark .next-input.next-input-textarea,.dark .next-input.next-medium{background-color:#303030!important;border-color:#8d8d93!important;caret-color:#c9c9cc!important}.dark .next-input.next-input-textarea em,.dark .next-input.next-input-textarea input,.dark .next-input.next-input-textarea textarea,.dark .next-input.next-medium em,.dark .next-input.next-medium input,.dark .next-input.next-medium textarea{color:#fff!important}.dark .next-input.next-input-textarea input::placeholder,.dark .next-input.next-medium input::placeholder{color:#929299}.dark .next-input.next-focus,.dark .next-input:hover{border-color:#b8b8bc!important}.dark .next-input.next-input-textarea,.dark .next-input.next-small{background-color:#303030!important;border-color:#8d8d93!important;caret-color:#c9c9cc!important}.dark .next-input.next-input-textarea em,.dark .next-input.next-input-textarea input,.dark .next-input.next-input-textarea textarea,.dark .next-input.next-small em,.dark .next-input.next-small input,.dark .next-input.next-small textarea{color:#fff!important}.dark .next-input.next-input-textarea input::placeholder,.dark .next-input.next-small input::placeholder{color:#929299}.dark .setting-box{background-color:#303030!important;color:#fff!important;border-color:#8d8d93}.dark .next-radio-group .next-radio-label{color:#c9c9cc!important}.dark .main-container{background-color:#161616}.dark .next-shell-brand .next-shell-main{color:#c9c9cc}.dark .next-shell-brand .next-shell-main h1{color:#fff}.dark .next-card-body,.dark .next-card-head,.dark .service-detail .cluster-card{background-color:#303030}.dark .next-card-title,.dark .next-form-item.next-small .next-form-item-label{color:#fff!important}.dark .next-card-subtitle{color:#c9c9cc}.dark .next-tag-group .next-tag-medium{color:#c9c9cc!important}.dark .next-form-item p{color:#c9c9cc}.dark .next-collapse-panel-title{background-color:#161616;color:#c9c9cc}.dark .next-collapse .next-collapse-panel-icon{color:#c9c9cc}.dark .next-collapse-panel-title:hover,.dark .next-collapse-panel-title:hover .next-collapse-panel-icon{background-color:#1c1d1f;color:#fff}.dark .next-collapse{border-color:#1c1d1f}.dark .next-collapse-panel-expanded>.next-collapse-panel-content{background-color:#2d2d2d}.dark .next-collapse-panel-expanded>.next-collapse-panel-content ul li pre{background-color:#303030;border-color:#1c1d1f;color:#c9c9cc}.dark .next-btn.next-btn-normal,.dark .next-btn.next-btn-secondary{background-color:#303030!important;border-color:#8d8d93!important;color:#c9c9cc!important}.dark .next-btn.next-btn-normal:hover,.dark .next-btn.next-btn-secondary:hover{background-color:#373737!important;color:#fff!important;border-color:#b8b8bc!important}.dark .next-pagination .next-pagination-item.next-current{background-color:#8d8d93!important;color:#fff!important}.dark .next-pagination.next-medium .next-pagination-item.next-next:not([disabled]) i,.dark .next-pagination.next-medium .next-pagination-item.next-prev:not([disabled]) i{color:#c9c9cc!important}.dark .next-switch-off .next-switch-btn,.dark .next-switch-on .next-switch-btn{background-color:#c9c9cc!important}.dark .next-switch-off:focus .next-switch-btn,.dark .next-switch-off:hover .next-switch-btn,.dark .next-switch-on:focus .next-switch-btn,.dark .next-switch-on:hover .next-switch-btn{background-color:#fff!important}.dark .next-switch-off{background-color:#303030!important;border-color:#8d8d93!important}.dark .next-switch-off:hover{border-color:#b8b8bc!important;background-color:#373737!important}:global(#root),body,html{height:100%}:global(.mainwrapper){position:absolute!important;top:0;bottom:0;left:0;right:0}:global(.sideleft){float:left;background-color:#eaedf1;position:absolute;top:0;bottom:0;z-index:2;overflow:hidden;width:180px}:global(.sideleft .toptitle){width:100%;height:70px;line-height:70px;background:#d9dee4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:700;text-indent:20px}:global(.maincontainer){position:absolute;width:auto;top:0;bottom:0;left:180px;right:0;overflow:hidden;overflow-y:auto;-o-transition:all .2s ease;-ms-transition:all .2s ease;-moz-transition:all .2s ease;-webkit-transition:all .2s ease}:global(.viewFramework-product-navbar .product-nav-list li .active){background-color:#fff!important}.next-menu .next-menu-icon-arrow-down{transform:rotate(0deg)!important}li.next-menu-item:not(.next-disabled).next-selected:focus:hover,li.next-menu-item:not(.next-disabled).next-selected:hover,li.next-menu-item:not(.next-disabled):hover{background:#e4f3fe;background:var(--nav-normal-sub-nav-hover-bg-color,#e4f3fe);color:#209bfa;color:var(--nav-normal-sub-nav-hover-text-color,#209bfa)}.next-menu.next-normal .next-menu-item.next-selected{background:#e4f3fe!important;background:var(--nav-normal-sub-nav-selected-bg-color,#e4f3fe)!important;color:#209bfa!important;color:var(--nav-normal-sub-nav-selected-text-color,#209bfa)!important}.clearfix:after{content:".";clear:both;display:block;height:0;overflow:hidden;visibility:hidden}.clearfix{zoom:1}.copy-icon{cursor:pointer;margin-left:4px;color:var(--color-link-1,#298dff)}.layouttitle{height:40px;width:200px;background-color:#09c;color:#fff;line-height:40px;text-align:center;margin:0;padding:0;font-weight:700}.linknav{height:30px;line-height:30px;text-align:center}.righttitle{height:40px;background-color:#000;width:100%;font-weight:700}.product-nav-icon{padding:15px 0 0;height:70px;margin:0}.envcontainer{padding-left:15px;margin-right:auto;margin-left:auto;max-height:450px;overflow:scroll;margin-bottom:100px;display:none;top:50px;left:230px;position:fixed;z-index:99999;width:435px;height:auto;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1)}.envtop{height:50px;line-height:50px;position:fixed;top:0;left:320px;z-index:999;background-color:transparent;-webkit-font-smoothing:antialiased}.envcontainer-top{padding-left:15px;margin-right:auto;margin-left:auto;max-height:450px;overflow:auto;margin-bottom:100px;display:none;top:50px;left:0;position:absolute;z-index:99999;width:435px;height:auto;background-color:#fff;border:1px solid #ddd;border-radius:0;-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1)}.envcontainer-top .row{margin:0!important}.envcontainer-top .active{background-color:#546478}.envcontainer dl dd.active{background-color:#546478;color:#fff}.current-env{display:block;padding:0;font-size:14px;margin:0 0 5px;text-align:center}.current-env a{color:#666;text-decoration:none}.product-nav-title{height:70px;line-height:70px;margin:0;text-align:center;padding:0;font-size:14px;background:#d9dee4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333}.console-title{padding:16px 0}.topbar-nav-item-title{margin:0 0 10px 31px;color:#666;font-weight:700}.dl{height:100%;width:125px;overflow:auto;margin:0 15px 15px 0}.dd{height:24px;line-height:24px;overflow-x:hidden;padding-left:12px;margin-left:20px}.active{color:#fff}.dd:hover{cursor:pointer;opacity:.7;filter:70}.cm-s-xq-light span.cm-keyword{line-height:1em;font-weight:700;color:#5a5cad}.cm-s-xq-light span.cm-atom{color:#6c8cd5}.cm-s-xq-light span.cm-number{color:#164}.cm-s-xq-light span.cm-def{text-decoration:underline}.cm-s-xq-light span.cm-type,.cm-s-xq-light span.cm-variable,.cm-s-xq-light span.cm-variable-2,.cm-s-xq-light span.cm-variable-3{color:#000}.cm-s-xq-light span.cm-comment{color:#0080ff;font-style:italic}.cm-s-xq-light span.cm-string{color:red}.cm-s-xq-light span.cm-meta{color:#ff0}.cm-s-xq-light span.cm-qualifier{color:grey}.cm-s-xq-light span.cm-builtin{color:#7ea656}.cm-s-xq-light span.cm-bracket{color:#cc7}.cm-s-xq-light span.cm-tag{color:#3f7f7f}.cm-s-xq-light span.cm-attribute{color:#7f007f}.cm-s-xq-light span.cm-error{color:red}.cm-s-xq-light .CodeMirror-activeline-background{background:#e8f2ff}.cm-s-xq-light .CodeMirror-matchingbracket{outline:1px solid grey;color:#000!important;background:#ff0}.CodeMirror{border:1px solid #eee}.CodeMirror-fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;height:auto;z-index:9999}.CodeMirror-lint-markers{width:16px}.CodeMirror-lint-tooltip{background-color:infobackground;border:1px solid #000;border-radius:4px 4px 4px 4px;color:infotext;font-family:monospace;font-size:10pt;overflow:hidden;padding:2px 5px;position:fixed;white-space:pre;white-space:pre-wrap;z-index:100;max-width:600px;opacity:0;transition:opacity .4s;-moz-transition:opacity .4s;-webkit-transition:opacity .4s;-o-transition:opacity .4s;-ms-transition:opacity .4s}.CodeMirror-lint-mark-error,.CodeMirror-lint-mark-warning{background-position:0 100%;background-repeat:repeat-x}.CodeMirror-lint-mark-error{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==")}.CodeMirror-lint-mark-warning{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=")}.CodeMirror-lint-marker-error,.CodeMirror-lint-marker-warning{background-position:50%;background-repeat:no-repeat;cursor:pointer;display:inline-block;height:16px;width:16px;vertical-align:middle;position:relative}.CodeMirror-lint-message-error,.CodeMirror-lint-message-warning{padding-left:18px;background-position:0 0;background-repeat:no-repeat}.CodeMirror-lint-marker-error,.CodeMirror-lint-message-error{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=")}.CodeMirror-lint-marker-warning,.CodeMirror-lint-message-warning{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=")}.CodeMirror-lint-marker-multiple{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC");background-repeat:no-repeat;background-position:100% 100%;width:100%;height:100%}@media(min-width:992px){.modal-lg{width:980px}}@media(min-width:768px)and (max-width:992px){.modal-lg{width:750px}}.modal-body table.narrow-table td{padding:8px 0}.add-on.form-control{margin-left:-4px;box-shadow:none;font-size:28px;line-height:32px;padding:0;vertical-align:top}.text-break{word-wrap:break-word;word-break:break-all;white-space:normal}.form-inline{margin-bottom:20px}.console-title{min-height:70px}.form-horizontal .form-group .checkbox{margin-left:0;margin-right:10px}.combox_border,.combox_select{border:1px solid #c2c2c2;width:245px}.combox_border{height:auto;display:inline-block;position:relative}.combox_input{border:0;padding-left:5px;width:85%;vertical-align:middle}.form-inline .combox_input.form-control{width:85%}.combox_button{width:12%;color:#666;text-align:center;vertical-align:middle;cursor:pointer;border-left:1px solid #c2c2c2}ul.combox_select{border-top:0;padding:0;position:absolute;left:-1px;top:20px;display:none;background:#fff;max-height:300px;overflow-y:auto}ul.combox_select li{overflow:hidden;height:30px;line-height:30px;cursor:pointer}ul.combox_select li a{display:block;line-height:28px;padding:0 8px;text-decoration:none;color:#666}ul.combox_select li a:hover{text-decoration:none;background:#f5f5f5}#combox-appanme.combox_border,#combox-appanme .combox_select{width:158px}#combox-appanme .form-control{height:30px}input.error,textarea.error{border:1px solid red}.form-inline .form-group{position:relative}label.error{margin:4px 0;color:red;font-weight:400;position:absolute;right:15px;bottom:-26px}ins{background-color:#c6ffc6;text-decoration:none}del{background-color:#ffc6c6}form.vertical-margin-lg .form-group{margin-bottom:22px}.namespacewrapper{padding:5px 15px;overflow:hidden;background-color:#efefef}.xrange-container{position:relative;border:1px solid #ccc;margin:0;padding:0}.xrange-container .cocofont,.xrange-container .iconfont{cursor:pointer}.xrange-container .label{display:flex;align-items:center;text-align:center;justify-content:space-between;cursor:pointer}.xrange-container .label.is-button{display:flex;border:1px solid #e6ebef;height:32px;padding:6px 12px;background-color:#f5f5f6}.xrange-container .label.is-button>i{font-size:13px}.xrange-container .label.is-empty{padding:0}.xrange-container .label.is-empty.is-button{padding:6px 12px}.xrange-container .label.is-empty>i{font-size:15px;margin-right:0}.xrange-container .label.is-empty>span,.xrange-container .label.is-empty b{display:none}.xrange-container .label>i{font-size:13px;text-align:center}.xrange-container .label>b{padding-top:3px}.xrange-container .label>span{min-width:100px;display:inline-flex;margin-bottom:8px}.xrange-layer{position:fixed;left:0;top:0;width:100%;height:100%;z-index:990;background-color:rgba(0,0,0,.05)}.xrange-panel{display:none;position:relative;right:1px;top:-8px;z-index:1000;border:1px solid #e6e7eb;border-radius:0;box-shadow:1px 1px 3px 0 transparent;width:111px;min-height:302px;background-color:#fff}.xrange-panel.visible{display:block}.xrange-panel .quick-list{display:flex;flex-direction:column;justify-content:space-around;box-sizing:content-box!important;align-items:center}.xrange-panel .quick-list>span{flex:0 0 auto;width:100%;line-height:20px;padding:6px 0 6px 27px;font-size:12px;-webkit-user-select:none;cursor:pointer}.xrange-panel .quick-list>span+span{margin-left:0}.xrange-panel .quick-list>span.active{background-color:#f2f3f7;color:#333;cursor:default}.xrange-panel .xrange-panel-footer{display:flex;align-items:center;justify-content:space-between;height:60px;background-color:#fff;position:absolute;top:300px;left:-539px;min-width:648px;padding:12px 108px 12px 12px}.xrange-panel .xrange-panel-footer .fn-left,.xrange-panel .xrange-panel-footer .fn-right{flex:0 0 auto}.xrange-panel .xrange-panel-footer button+button{margin-left:8px}.xrange-panel .picker-container{display:none;position:relative;margin-top:16px}.xrange-panel .picker-container .next-range-picker-panel{top:-273px!important;left:-540px!important;position:absolute!important;animation:none!important;z-index:999999;border-color:#e6ebef}.next-calendar-card .next-calendar-range-body{background:#fff!important;min-height:227px!important}.xrange-panel .picker-container+.next-range-picker{display:none}.xrange-panel .picker-container .next-date-picker-quick-tool{display:none!important}.xrange-panel.show-picker .picker-container{display:block;min-height:5px}.dingding{background:url(https://g.alicdn.com/cm-design/arms/1.1.27/styles/arms/images/dingding.png) no-repeat 0}.dingding,.wangwang{display:inline-block;padding:5px 0 5px 30px;height:24px;vertical-align:middle}.wangwang{background:url(https://g.alicdn.com/cm-design/arms/1.1.27/styles/arms/images/wangwang.png) no-repeat 0;background-size:24px}@media screen and (min-width:768px){.region-group-list{max-width:784px}}@media screen and (min-width:992px){.region-group-list{max-width:862px}}@media screen and (min-width:1200px){.region-group-list{max-width:600px}}@media screen and (min-width:1330px){.region-group-list{max-width:700px}}@media screen and (min-width:1500px){.region-group-list{max-width:1000px}}.next-switch-medium{border:1px solid transparent;width:48px!important;height:26px!important;border-radius:15px!important}.next-switch-medium>.next-switch-trigger{border:1px solid transparent;position:absolute;left:33px!important;width:24px!important;height:24px!important;border-radius:15px!important}.aliyun-advice{bottom:98px!important}.next-switch-medium>.next-switch-children{font-size:12px!important;position:absolute;height:24px!important;line-height:24px!important}.next-switch-on>.next-switch-trigger{box-shadow:1px 1px 3px 0 rgba(0,0,0,.32)!important;background-color:#fff;border-color:transparent;position:absolute;right:0!important}.next-switch-on>.next-switch-children{left:2px!important;font-size:12px!important}.next-switch-on[disabled]>.next-switch-trigger{position:absolute;right:0!important;box-shadow:1px 1px 3px 0 rgba(0,0,0,.32)!important;background-color:#e6e7eb;border-color:transparent}.next-switch-off>.next-switch-children{right:-6px;color:#979a9c!important}.next-switch-off[disabled]>.next-switch-trigger{left:0!important;box-shadow:1px 1px 3px 0 rgba(0,0,0,.32)!important;background-color:#e6e7eb;border-color:transparent}.next-switch-off>.next-switch-trigger{left:0!important;box-shadow:1px 1px 3px 0 rgba(0,0,0,.32);background-color:#fff;border-color:transparent}.next-switch-off,.next-switch-on{width:58px!important}.next-switch-on{position:relative}.next-menu .next-menu-icon-select{position:absolute;left:4px;top:0;color:#73777a!important}.next-table-cell-wrapper{hyphens:auto!important;word-break:break-word!important}.dash-page-container{height:100%;min-width:980px}.dash-page-container:after{content:"";display:table;clear:both}.dash-left-container{position:relative;float:left;width:77.52%;height:100%}.dash-title-show{width:100%;height:106px;background-color:#fff;box-shadow:0 0 0 0 hsla(0,0%,85.1%,.5),0 0 2px 0 rgba(0,0,0,.12);margin-bottom:19px;padding-top:20px;padding-bottom:20px;overflow:hidden}.dash-title-item{float:left;height:49px;width:33%;border-right:1px solid #ebecec;line-height:49px;padding-left:30px;padding-right:30px}.dash-title-word{height:19px;line-height:19px;font-size:14px;color:#73777a}.dash-title-num{height:45px;font-size:32px}.dash-title-item:last-child{border:none!important}.dash-menu-list{width:100%;height:104px;background-color:#fff;box-shadow:0 0 0 0 hsla(0,0%,85.1%,.5),0 0 2px 0 rgba(0,0,0,.12);margin-bottom:19px}.dash-menu-item{position:relative;float:left;width:33.33%;border-right:1px solid #eee;height:100%;padding-top:20px;padding-bottom:20px;cursor:pointer}.dash-menu-item.disabled{cursor:not-allowed;opacity:.7}.dash-menu-item:last-child{border:none}.dash-menu-item:hover{box-shadow:0 3px 6px 0 rgba(0,0,0,.12)}.dash-menu-conent-wrapper{padding-left:60px;padding-right:40px}.dash-menu-pic{position:absolute;width:32px;left:20px}.dash-menu-content-title{height:19px;line-height:19px;color:#373d41;margin-bottom:5px}.dash-menu-content-word{font-size:12px;color:#73777a}.dash-scene-wrapper{width:100%;background-color:#fff;box-shadow:0 0 0 0 hsla(0,0%,85.1%,.5),0 0 2px 0 rgba(0,0,0,.12);margin-bottom:20px}.dash-scene-title{position:relative;padding-left:20px;height:50px;line-height:50px;border-bottom:1px solid #f0f0f0}.dash-sceneitem{width:100%;height:80px;padding-top:24px}.dash-scenitem-out{border-bottom:1px solid #eee;height:100%}.dash-sceneitem:hover{box-shadow:0 0 0 0 hsla(0,0%,85.1%,.5),0 0 4px 0 rgba(0,0,0,.12);border-bottom:1px solid #f0f0f0}.dash-sceneitem-progresswrapper{position:relative;width:256px;height:6px}.dash-sceneitem-progresswrapper.green{background-color:#e2f5cf}.dash-sceneitem-progresswrapper.red{background-color:#ffe6e5}.dash-sceneitem-progresswrapper.green .dash-sceneitem-progressinner{height:100%;background-color:#a6e22e}.dash-sceneitem-progresswrapper.red .dash-sceneitem-progressinner{height:100%;background-color:#eb4c4d}.dash-sceneitem-iconshow{position:absolute;right:0;top:5px}.dash-sceneitem:hover.dash-sceneitem-out{border:none}.dash-sceneitem:after{display:table;content:"";clear:both}.dash-sceneitem-title{float:left;height:32.8px;padding-top:5px;width:14.47%;border-right:1px solid #f0f0f0;overflow:hidden;text-overflow:ellipsis}.scene-nomore-data{position:absolute;text-align:center;left:0;right:0;color:#eee;font-size:12px}.dash-sceneitem-content{position:relative;float:left;padding-top:5px;padding-left:30px;width:85.53%}.scene-title-link{position:absolute;right:20px;top:0;font-size:10px}.dash-bottom-show{width:100%;height:42px;line-height:42px;margin-top:18px;text-align:center;background-color:#fff;box-shadow:0 0 0 0 hsla(0,0%,85.1%,.5),0 0 2px 0 rgba(0,0,0,.12)}.dash-right-container{float:right;height:100%;width:22.44%;padding:10px;background-color:#fff}.dash-bottom-item,.dash-vl{color:#979a9c;margin-right:10px}.dash-doc{background-color:#fff;height:178px;width:100%;margin-bottom:14px}.dash-doc-title{width:100%;height:68px;line-height:68px;padding-left:20px;padding-right:20px;border-bottom:1px solid #eee}.dash-doc-content{width:100%;padding:15px}.dash-card-contentwrappers{width:100%;height:230px;margin-bottom:14px;background-color:#fff;border:1px solid #eee;box-shadow:0 0 0 0 hsla(0,0%,85.1%,.5),0 0 2px 0 rgba(0,0,0,.12)}.dash-card-title{width:100%;height:39px;line-height:39px;margin:0;padding-left:24px;padding-right:24px;color:#4a4a4a;border-bottom:1px solid #eee}.dash-card-contentlist{padding:20px}.dash-card-contentitem{position:relative;text-align:left;font-size:12px;margin-bottom:10px}.next-slick-dots-item button{height:4px!important;width:35px!important;border-radius:10px!important}.next-table-row.hovered{background-color:#f5f7f9!important}.alert-success-text{color:#4a4a4a;font-size:14px;margin:10px 0}.alert-success{border-color:#e0e0e0!important}.row-bg-green{background-color:#e4fdda!important}.row-bg-light-green{background-color:#e3fff8}.row-bg-orange{background-color:#fff3e0}.row-bg-red{background-color:#ffece4!important}/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}*,:after,:before{box-sizing:border-box}ol,ul{list-style:none;margin:0;padding:0}li{margin-left:0}hr{border:solid #e6e6e6;border-width:1px 0 0}a{text-decoration:none}a:link{color:#298dff}a:visited{color:#4a83c5}a:active,a:hover{color:#2580e7}a:active{text-decoration:underline}@font-face{font-family:Roboto;src:url(../console-ui/public/fonts/roboto-thin.eot);src:url(../console-ui/public/fonts/roboto-thin.eot?#iefix) format("embedded-opentype"),url(../console-ui/public/fonts/roboto-thin.woff2) format("woff2"),url(../console-ui/public/fonts/roboto-thin.woff) format("woff"),url(../console-ui/public/fonts/roboto-thin.ttf) format("truetype");font-weight:200;font-display:swap}@font-face{font-family:Roboto;src:url(../console-ui/public/fonts/roboto-light.eot);src:url(../console-ui/public/fonts/roboto-light.eot?#iefix) format("embedded-opentype"),url(../console-ui/public/fonts/roboto-light.woff2) format("woff2"),url(../console-ui/public/fonts/roboto-light.woff) format("woff"),url(../console-ui/public/fonts/roboto-light.ttf) format("truetype");font-weight:300;font-display:swap}@font-face{font-family:Roboto;src:url(../console-ui/public/fonts/roboto-regular.eot);src:url(../console-ui/public/fonts/roboto-regular.eot?#iefix) format("embedded-opentype"),url(../console-ui/public/fonts/roboto-regular.woff2) format("woff2"),url(../console-ui/public/fonts/roboto-regular.woff) format("woff"),url(../console-ui/public/fonts/roboto-regular.ttf) format("truetype");font-weight:400;font-display:swap}@font-face{font-family:Roboto;src:url(../console-ui/public/fonts/roboto-medium.eot);src:url(../console-ui/public/fonts/roboto-medium.eot?#iefix) format("embedded-opentype"),url(../console-ui/public/fonts/roboto-medium.woff2) format("woff2"),url(../console-ui/public/fonts/roboto-medium.woff) format("woff"),url(../console-ui/public/fonts/roboto-medium.ttf) format("truetype");font-weight:500;font-display:swap}@font-face{font-family:Roboto;src:url(../console-ui/public/fonts/roboto-bold.eot);src:url(../console-ui/public/fonts/roboto-bold.eot?#iefix) format("embedded-opentype"),url(../console-ui/public/fonts/roboto-bold.woff2) format("woff2"),url(../console-ui/public/fonts/roboto-bold.woff) format("woff"),url(../console-ui/public/fonts/roboto-bold.ttf) format("truetype");font-weight:700;font-display:swap}html{font-size:100%}body{font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142;color:#333}button,input,optgroup,select,textarea{font-family:inherit}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{font-weight:inherit}h1{margin-bottom:12px;font-size:24px;line-height:36px}h1,h2{font-weight:500}h2{margin-bottom:10px;font-size:20px;line-height:30px}h3,h4{margin-bottom:8px;font-size:16px}h3,h4,h5{font-weight:400;line-height:24px}h5{margin-bottom:7px;font-size:14px}h6{font-weight:500}h6,p{margin-bottom:7px;font-size:14px;line-height:20px}p{font-weight:400}strong{font-weight:500}small{font-size:75%}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-moz-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-ms-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-o-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-100px);-moz-transform:translateY(-100px);-ms-transform:translateY(-100px);-o-transform:translateY(-100px);transform:translateY(-100px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-100px);-moz-transform:translateY(-100px);-ms-transform:translateY(-100px);-o-transform:translateY(-100px);transform:translateY(-100px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-ms-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-100px);-moz-transform:translateY(-100px);-ms-transform:translateY(-100px);-o-transform:translateY(-100px);transform:translateY(-100px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-o-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-100px);-moz-transform:translateY(-100px);-ms-transform:translateY(-100px);-o-transform:translateY(-100px);transform:translateY(-100px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-100px);-moz-transform:translateY(-100px);-ms-transform:translateY(-100px);-o-transform:translateY(-100px);transform:translateY(-100px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeInDownSmall{0%{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes fadeInDownSmall{0%{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-ms-keyframes fadeInDownSmall{0%{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-o-keyframes fadeInDownSmall{0%{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInDownSmall{0%{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-moz-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-ms-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-o-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-moz-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-ms-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-o-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(24px);-moz-transform:translateY(24px);-ms-transform:translateY(24px);-o-transform:translateY(24px);transform:translateY(24px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(24px);-moz-transform:translateY(24px);-ms-transform:translateY(24px);-o-transform:translateY(24px);transform:translateY(24px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-ms-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(24px);-moz-transform:translateY(24px);-ms-transform:translateY(24px);-o-transform:translateY(24px);transform:translateY(24px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-o-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(24px);-moz-transform:translateY(24px);-ms-transform:translateY(24px);-o-transform:translateY(24px);transform:translateY(24px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(24px);-moz-transform:translateY(24px);-ms-transform:translateY(24px);-o-transform:translateY(24px);transform:translateY(24px)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@-moz-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@-ms-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@-o-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@-webkit-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-ms-transform:translateY(20px);-o-transform:translateY(20px);transform:translateY(20px)}}@-moz-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-ms-transform:translateY(20px);-o-transform:translateY(20px);transform:translateY(20px)}}@-ms-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-ms-transform:translateY(20px);-o-transform:translateY(20px);transform:translateY(20px)}}@-o-keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-ms-transform:translateY(20px);-o-transform:translateY(20px);transform:translateY(20px)}}@keyframes fadeOutDown{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-ms-transform:translateY(20px);-o-transform:translateY(20px);transform:translateY(20px)}}@-webkit-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}}@-moz-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}}@-ms-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}}@-o-keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}}@keyframes fadeOutLeft{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-20px);-moz-transform:translateX(-20px);-ms-transform:translateX(-20px);-o-transform:translateX(-20px);transform:translateX(-20px)}}@-webkit-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}}@-moz-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}}@-ms-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}}@-o-keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}}@keyframes fadeOutRight{0%{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(20px);-moz-transform:translateX(20px);-ms-transform:translateX(20px);-o-transform:translateX(20px);transform:translateX(20px)}}@-webkit-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-24px);-moz-transform:translateY(-24px);-ms-transform:translateY(-24px);-o-transform:translateY(-24px);transform:translateY(-24px)}}@-moz-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-24px);-moz-transform:translateY(-24px);-ms-transform:translateY(-24px);-o-transform:translateY(-24px);transform:translateY(-24px)}}@-ms-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-24px);-moz-transform:translateY(-24px);-ms-transform:translateY(-24px);-o-transform:translateY(-24px);transform:translateY(-24px)}}@-o-keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-24px);-moz-transform:translateY(-24px);-ms-transform:translateY(-24px);-o-transform:translateY(-24px);transform:translateY(-24px)}}@keyframes fadeOutUp{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-24px);-moz-transform:translateY(-24px);-ms-transform:translateY(-24px);-o-transform:translateY(-24px);transform:translateY(-24px)}}@-webkit-keyframes fadeOutUpSmall{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}}@-moz-keyframes fadeOutUpSmall{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}}@-ms-keyframes fadeOutUpSmall{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}}@-o-keyframes fadeOutUpSmall{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}}@keyframes fadeOutUpSmall{0%{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);-ms-transform:translateY(-8px);-o-transform:translateY(-8px);transform:translateY(-8px)}}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(2000px);-moz-transform:translateY(2000px);-ms-transform:translateY(2000px);-o-transform:translateY(2000px);transform:translateY(2000px)}}@-moz-keyframes slideOutDown{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(2000px);-moz-transform:translateY(2000px);-ms-transform:translateY(2000px);-o-transform:translateY(2000px);transform:translateY(2000px)}}@-ms-keyframes slideOutDown{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(2000px);-moz-transform:translateY(2000px);-ms-transform:translateY(2000px);-o-transform:translateY(2000px);transform:translateY(2000px)}}@-o-keyframes slideOutDown{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(2000px);-moz-transform:translateY(2000px);-ms-transform:translateY(2000px);-o-transform:translateY(2000px);transform:translateY(2000px)}}@keyframes slideOutDown{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(2000px);-moz-transform:translateY(2000px);-ms-transform:translateY(2000px);-o-transform:translateY(2000px);transform:translateY(2000px)}}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-2000px);-moz-transform:translateX(-2000px);-ms-transform:translateX(-2000px);-o-transform:translateX(-2000px);transform:translateX(-2000px)}}@-moz-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-2000px);-moz-transform:translateX(-2000px);-ms-transform:translateX(-2000px);-o-transform:translateX(-2000px);transform:translateX(-2000px)}}@-ms-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-2000px);-moz-transform:translateX(-2000px);-ms-transform:translateX(-2000px);-o-transform:translateX(-2000px);transform:translateX(-2000px)}}@-o-keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-2000px);-moz-transform:translateX(-2000px);-ms-transform:translateX(-2000px);-o-transform:translateX(-2000px);transform:translateX(-2000px)}}@keyframes slideOutLeft{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(-2000px);-moz-transform:translateX(-2000px);-ms-transform:translateX(-2000px);-o-transform:translateX(-2000px);transform:translateX(-2000px)}}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(2000px);-moz-transform:translateX(2000px);-ms-transform:translateX(2000px);-o-transform:translateX(2000px);transform:translateX(2000px)}}@-moz-keyframes slideOutRight{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(2000px);-moz-transform:translateX(2000px);-ms-transform:translateX(2000px);-o-transform:translateX(2000px);transform:translateX(2000px)}}@-ms-keyframes slideOutRight{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(2000px);-moz-transform:translateX(2000px);-ms-transform:translateX(2000px);-o-transform:translateX(2000px);transform:translateX(2000px)}}@-o-keyframes slideOutRight{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(2000px);-moz-transform:translateX(2000px);-ms-transform:translateX(2000px);-o-transform:translateX(2000px);transform:translateX(2000px)}}@keyframes slideOutRight{0%{-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}to{opacity:0;-webkit-transform:translateX(2000px);-moz-transform:translateX(2000px);-ms-transform:translateX(2000px);-o-transform:translateX(2000px);transform:translateX(2000px)}}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-2000px);-moz-transform:translateY(-2000px);-ms-transform:translateY(-2000px);-o-transform:translateY(-2000px);transform:translateY(-2000px)}}@-moz-keyframes slideOutUp{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-2000px);-moz-transform:translateY(-2000px);-ms-transform:translateY(-2000px);-o-transform:translateY(-2000px);transform:translateY(-2000px)}}@-ms-keyframes slideOutUp{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-2000px);-moz-transform:translateY(-2000px);-ms-transform:translateY(-2000px);-o-transform:translateY(-2000px);transform:translateY(-2000px)}}@-o-keyframes slideOutUp{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-2000px);-moz-transform:translateY(-2000px);-ms-transform:translateY(-2000px);-o-transform:translateY(-2000px);transform:translateY(-2000px)}}@keyframes slideOutUp{0%{-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}to{opacity:0;-webkit-transform:translateY(-2000px);-moz-transform:translateY(-2000px);-ms-transform:translateY(-2000px);-o-transform:translateY(-2000px);transform:translateY(-2000px)}}@-webkit-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-ms-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-o-keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@keyframes slideInDown{0%{opacity:0;-webkit-transform:translateY(-100%);-moz-transform:translateY(-100%);-ms-transform:translateY(-100%);-o-transform:translateY(-100%);transform:translateY(-100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-ms-transform:translateX(-100%);-o-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-moz-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-ms-transform:translateX(-100%);-o-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-ms-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-ms-transform:translateX(-100%);-o-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-o-keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-ms-transform:translateX(-100%);-o-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@keyframes slideInLeft{0%{opacity:0;-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);-ms-transform:translateX(-100%);-o-transform:translateX(-100%);transform:translateX(-100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-moz-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-ms-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-o-keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@keyframes slideInRight{0%{opacity:0;-webkit-transform:translateX(100%);-moz-transform:translateX(100%);-ms-transform:translateX(100%);-o-transform:translateX(100%);transform:translateX(100%)}to{opacity:1;-webkit-transform:translateX(0);-moz-transform:translateX(0);-ms-transform:translateX(0);-o-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes slideInUp{0%{opacity:0;-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);-o-transform:translateY(100%);transform:translateY(100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-moz-keyframes slideInUp{0%{opacity:0;-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);-o-transform:translateY(100%);transform:translateY(100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-ms-keyframes slideInUp{0%{opacity:0;-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);-o-transform:translateY(100%);transform:translateY(100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-o-keyframes slideInUp{0%{opacity:0;-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);-o-transform:translateY(100%);transform:translateY(100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@keyframes slideInUp{0%{opacity:0;-webkit-transform:translateY(100%);-moz-transform:translateY(100%);-ms-transform:translateY(100%);-o-transform:translateY(100%);transform:translateY(100%)}to{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@-moz-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@-ms-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@-o-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@-moz-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@-ms-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@-o-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);-moz-transform:scale3d(.3,.3,.3);-ms-transform:scale3d(.3,.3,.3);-o-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@-webkit-keyframes zoomInBig{0%{opacity:0;-webkit-transform:scale(.9);-moz-transform:scale(.9);-ms-transform:scale(.9);-o-transform:scale(.9);transform:scale(.9)}to{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-moz-keyframes zoomInBig{0%{opacity:0;-webkit-transform:scale(.9);-moz-transform:scale(.9);-ms-transform:scale(.9);-o-transform:scale(.9);transform:scale(.9)}to{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-ms-keyframes zoomInBig{0%{opacity:0;-webkit-transform:scale(.9);-moz-transform:scale(.9);-ms-transform:scale(.9);-o-transform:scale(.9);transform:scale(.9)}to{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-o-keyframes zoomInBig{0%{opacity:0;-webkit-transform:scale(.9);-moz-transform:scale(.9);-ms-transform:scale(.9);-o-transform:scale(.9);transform:scale(.9)}to{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes zoomInBig{0%{opacity:0;-webkit-transform:scale(.9);-moz-transform:scale(.9);-ms-transform:scale(.9);-o-transform:scale(.9);transform:scale(.9)}to{opacity:1;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-webkit-keyframes zoomOutBig{0%{opacity:1}to{opacity:0;-webkit-transform:scale(.8);-moz-transform:scale(.8);-ms-transform:scale(.8);-o-transform:scale(.8);transform:scale(.8)}}@-moz-keyframes zoomOutBig{0%{opacity:1}to{opacity:0;-webkit-transform:scale(.8);-moz-transform:scale(.8);-ms-transform:scale(.8);-o-transform:scale(.8);transform:scale(.8)}}@-ms-keyframes zoomOutBig{0%{opacity:1}to{opacity:0;-webkit-transform:scale(.8);-moz-transform:scale(.8);-ms-transform:scale(.8);-o-transform:scale(.8);transform:scale(.8)}}@-o-keyframes zoomOutBig{0%{opacity:1}to{opacity:0;-webkit-transform:scale(.8);-moz-transform:scale(.8);-ms-transform:scale(.8);-o-transform:scale(.8);transform:scale(.8)}}@keyframes zoomOutBig{0%{opacity:1}to{opacity:0;-webkit-transform:scale(.8);-moz-transform:scale(.8);-ms-transform:scale(.8);-o-transform:scale(.8);transform:scale(.8)}}@-webkit-keyframes expandInDown{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-moz-keyframes expandInDown{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-ms-keyframes expandInDown{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-o-keyframes expandInDown{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@keyframes expandInDown{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-webkit-keyframes expandInUp{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-moz-keyframes expandInUp{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-ms-keyframes expandInUp{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-o-keyframes expandInUp{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@keyframes expandInUp{0%{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-webkit-keyframes expandInWithFade{0%{opacity:0}40%{opacity:.1}50%{opacity:.9}to{opacity:1}}@-moz-keyframes expandInWithFade{0%{opacity:0}40%{opacity:.1}50%{opacity:.9}to{opacity:1}}@-ms-keyframes expandInWithFade{0%{opacity:0}40%{opacity:.1}50%{opacity:.9}to{opacity:1}}@-o-keyframes expandInWithFade{0%{opacity:0}40%{opacity:.1}50%{opacity:.9}to{opacity:1}}@keyframes expandInWithFade{0%{opacity:0}40%{opacity:.1}50%{opacity:.9}to{opacity:1}}@-webkit-keyframes expandOutUp{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-moz-keyframes expandOutUp{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-ms-keyframes expandOutUp{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-o-keyframes expandOutUp{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@keyframes expandOutUp{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left top 0;-moz-transform-origin:left top 0;-ms-transform-origin:left top 0;-o-transform-origin:left top 0;transform-origin:left top 0}}@-webkit-keyframes expandOutDown{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-moz-keyframes expandOutDown{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-ms-keyframes expandOutDown{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-o-keyframes expandOutDown{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@keyframes expandOutDown{0%{opacity:1;-webkit-transform:scaleY(1);-moz-transform:scaleY(1);-ms-transform:scaleY(1);-o-transform:scaleY(1);transform:scaleY(1);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}to{opacity:0;-webkit-transform:scaleY(.6);-moz-transform:scaleY(.6);-ms-transform:scaleY(.6);-o-transform:scaleY(.6);transform:scaleY(.6);-webkit-transform-origin:left bottom 0;-moz-transform-origin:left bottom 0;-ms-transform-origin:left bottom 0;-o-transform-origin:left bottom 0;transform-origin:left bottom 0}}@-webkit-keyframes expandOutWithFade{0%{opacity:1}70%{opacity:0}to{opacity:0}}@-moz-keyframes expandOutWithFade{0%{opacity:1}70%{opacity:0}to{opacity:0}}@-ms-keyframes expandOutWithFade{0%{opacity:1}70%{opacity:0}to{opacity:0}}@-o-keyframes expandOutWithFade{0%{opacity:1}70%{opacity:0}to{opacity:0}}@keyframes expandOutWithFade{0%{opacity:1}70%{opacity:0}to{opacity:0}}@-webkit-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}20%{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2)}to{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-moz-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}20%{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2)}to{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-ms-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}20%{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2)}to{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-o-keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}20%{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2)}to{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@keyframes pulse{0%{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}20%{-webkit-transform:scale(1.2);-moz-transform:scale(1.2);-ms-transform:scale(1.2);-o-transform:scale(1.2);transform:scale(1.2)}to{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}.fadeIn{-webkit-animation-name:fadeIn;-moz-animation-name:fadeIn;-ms-animation-name:fadeIn;-o-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.fadeInDown{-webkit-animation-name:fadeInDown;-moz-animation-name:fadeInDown;-ms-animation-name:fadeInDown;-o-animation-name:fadeInDown;animation-name:fadeInDown;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeInDown,.fadeInLeft{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.fadeInLeft{-webkit-animation-name:fadeInLeft;-moz-animation-name:fadeInLeft;-ms-animation-name:fadeInLeft;-o-animation-name:fadeInLeft;animation-name:fadeInLeft;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeInRight{-webkit-animation-name:fadeInRight;-moz-animation-name:fadeInRight;-ms-animation-name:fadeInRight;-o-animation-name:fadeInRight;animation-name:fadeInRight;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeInRight,.fadeInUp{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.fadeInUp{-webkit-animation-name:fadeInUp;-moz-animation-name:fadeInUp;-ms-animation-name:fadeInUp;-o-animation-name:fadeInUp;animation-name:fadeInUp;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeOut{-webkit-animation-name:fadeOut;-moz-animation-name:fadeOut;-ms-animation-name:fadeOut;-o-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.35s;-moz-animation-duration:.35s;-ms-animation-duration:.35s;-o-animation-duration:.35s;animation-duration:.35s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeOut,.fadeOutDown{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.fadeOutDown{-webkit-animation-name:fadeOutDown;-moz-animation-name:fadeOutDown;-ms-animation-name:fadeOutDown;-o-animation-name:fadeOutDown;animation-name:fadeOutDown;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.25s;-moz-animation-duration:.25s;-ms-animation-duration:.25s;-o-animation-duration:.25s;animation-duration:.25s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;-moz-animation-name:fadeOutLeft;-ms-animation-name:fadeOutLeft;-o-animation-name:fadeOutLeft;animation-name:fadeOutLeft;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.25s;-moz-animation-duration:.25s;-ms-animation-duration:.25s;-o-animation-duration:.25s;animation-duration:.25s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeOutLeft,.fadeOutRight{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.fadeOutRight{-webkit-animation-name:fadeOutRight;-moz-animation-name:fadeOutRight;-ms-animation-name:fadeOutRight;-o-animation-name:fadeOutRight;animation-name:fadeOutRight;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.25s;-moz-animation-duration:.25s;-ms-animation-duration:.25s;-o-animation-duration:.25s;animation-duration:.25s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeOutUp{-webkit-animation-name:fadeOutUp;-moz-animation-name:fadeOutUp;-ms-animation-name:fadeOutUp;-o-animation-name:fadeOutUp;animation-name:fadeOutUp;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.25s;-moz-animation-duration:.25s;-ms-animation-duration:.25s;-o-animation-duration:.25s;animation-duration:.25s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.slideInUp{-webkit-animation-name:slideInUp;-moz-animation-name:slideInUp;-ms-animation-name:slideInUp;-o-animation-name:slideInUp;animation-name:slideInUp;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.35s;-moz-animation-duration:.35s;-ms-animation-duration:.35s;-o-animation-duration:.35s;animation-duration:.35s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideInDown,.slideInUp{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.slideInDown{-webkit-animation-name:slideInDown;-moz-animation-name:slideInDown;-ms-animation-name:slideInDown;-o-animation-name:slideInDown;animation-name:slideInDown;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.35s;-moz-animation-duration:.35s;-ms-animation-duration:.35s;-o-animation-duration:.35s;animation-duration:.35s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideInLeft{-webkit-animation-name:slideInLeft;-moz-animation-name:slideInLeft;-ms-animation-name:slideInLeft;-o-animation-name:slideInLeft;animation-name:slideInLeft;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.35s;-moz-animation-duration:.35s;-ms-animation-duration:.35s;-o-animation-duration:.35s;animation-duration:.35s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideInLeft,.slideInRight{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.slideInRight{-webkit-animation-name:slideInRight;-moz-animation-name:slideInRight;-ms-animation-name:slideInRight;-o-animation-name:slideInRight;animation-name:slideInRight;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.35s;-moz-animation-duration:.35s;-ms-animation-duration:.35s;-o-animation-duration:.35s;animation-duration:.35s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideOutUp{-webkit-animation-name:slideOutUp;-moz-animation-name:slideOutUp;-ms-animation-name:slideOutUp;-o-animation-name:slideOutUp;animation-name:slideOutUp;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideOutRight,.slideOutUp{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.slideOutRight{-webkit-animation-name:slideOutRight;-moz-animation-name:slideOutRight;-ms-animation-name:slideOutRight;-o-animation-name:slideOutRight;animation-name:slideOutRight;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideOutLeft{-webkit-animation-name:slideOutLeft;-moz-animation-name:slideOutLeft;-ms-animation-name:slideOutLeft;-o-animation-name:slideOutLeft;animation-name:slideOutLeft;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.slideOutDown,.slideOutLeft{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.slideOutDown{-webkit-animation-name:slideOutDown;-moz-animation-name:slideOutDown;-ms-animation-name:slideOutDown;-o-animation-name:slideOutDown;animation-name:slideOutDown;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.zoomIn{-webkit-animation-name:zoomIn;-moz-animation-name:zoomIn;-ms-animation-name:zoomIn;-o-animation-name:zoomIn;animation-name:zoomIn;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.zoomIn,.zoomOut{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.zoomOut{-webkit-animation-name:zoomOut;-moz-animation-name:zoomOut;-ms-animation-name:zoomOut;-o-animation-name:zoomOut;animation-name:zoomOut;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.expandInDown{-webkit-animation-name:expandInDown;-moz-animation-name:expandInDown;-ms-animation-name:expandInDown;-o-animation-name:expandInDown;animation-name:expandInDown;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.expandInDown,.expandOutUp{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.expandOutUp{-webkit-animation-name:expandOutUp;-moz-animation-name:expandOutUp;-ms-animation-name:expandOutUp;-o-animation-name:expandOutUp;animation-name:expandOutUp;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.15s;-moz-animation-duration:.15s;-ms-animation-duration:.15s;-o-animation-duration:.15s;animation-duration:.15s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.expandInUp{-webkit-animation-name:expandInUp;-moz-animation-name:expandInUp;-ms-animation-name:expandInUp;-o-animation-name:expandInUp;animation-name:expandInUp;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.expandInUp,.expandOutDown{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.expandOutDown{-webkit-animation-name:expandOutDown;-moz-animation-name:expandOutDown;-ms-animation-name:expandOutDown;-o-animation-name:expandOutDown;animation-name:expandOutDown;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.15s;-moz-animation-duration:.15s;-ms-animation-duration:.15s;-o-animation-duration:.15s;animation-duration:.15s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeInDownSmall{-webkit-animation-name:fadeInDownSmall;-moz-animation-name:fadeInDownSmall;-ms-animation-name:fadeInDownSmall;-o-animation-name:fadeInDownSmall;animation-name:fadeInDownSmall;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.fadeInDownSmall,.fadeOutUpSmall{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.fadeOutUpSmall{-webkit-animation-name:fadeOutUpSmall;-moz-animation-name:fadeOutUpSmall;-ms-animation-name:fadeOutUpSmall;-o-animation-name:fadeOutUpSmall;animation-name:fadeOutUpSmall;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.25s;-moz-animation-duration:.25s;-ms-animation-duration:.25s;-o-animation-duration:.25s;animation-duration:.25s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.zoomInBig{-webkit-animation-name:zoomInBig;-moz-animation-name:zoomInBig;-ms-animation-name:zoomInBig;-o-animation-name:zoomInBig;animation-name:zoomInBig;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.2s;-moz-animation-duration:.2s;-ms-animation-duration:.2s;-o-animation-duration:.2s;animation-duration:.2s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);-moz-animation-timing-function:cubic-bezier(0,0,.2,1);-ms-animation-timing-function:cubic-bezier(0,0,.2,1);-o-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.zoomInBig,.zoomOutBig{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.zoomOutBig{-webkit-animation-name:zoomOutBig;-moz-animation-name:zoomOutBig;-ms-animation-name:zoomOutBig;-o-animation-name:zoomOutBig;animation-name:zoomOutBig;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.2s;-moz-animation-duration:.2s;-ms-animation-duration:.2s;-o-animation-duration:.2s;animation-duration:.2s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);-moz-animation-timing-function:cubic-bezier(0,0,.2,1);-ms-animation-timing-function:cubic-bezier(0,0,.2,1);-o-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both}.pulse{-webkit-animation-name:pulse;-moz-animation-name:pulse;-ms-animation-name:pulse;-o-animation-name:pulse;animation-name:pulse;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.3s;-moz-animation-duration:.3s;-ms-animation-duration:.3s;-o-animation-duration:.3s;animation-duration:.3s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.4,0,.2,1);-moz-animation-timing-function:cubic-bezier(.4,0,.2,1);-ms-animation-timing-function:cubic-bezier(.4,0,.2,1);-o-animation-timing-function:cubic-bezier(.4,0,.2,1);animation-timing-function:cubic-bezier(.4,0,.2,1);-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.expand-enter{overflow:hidden}.expand-enter-active{transition:all .3s ease-out}.expand-enter-active>*{-webkit-animation-name:expandInWithFade;-moz-animation-name:expandInWithFade;-ms-animation-name:expandInWithFade;-o-animation-name:expandInWithFade;animation-name:expandInWithFade;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.2s;-moz-animation-duration:.2s;-ms-animation-duration:.2s;-o-animation-duration:.2s;animation-duration:.2s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:forwards;-moz-animation-fill-mode:forwards;-ms-animation-fill-mode:forwards;-o-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.expand-leave{overflow:hidden}.expand-leave-active{transition:all .2s ease-out}.expand-leave-active>*{-webkit-animation-name:expandOutWithFade;-moz-animation-name:expandOutWithFade;-ms-animation-name:expandOutWithFade;-o-animation-name:expandOutWithFade;animation-name:expandOutWithFade;-webkit-animation-iteration-count:1;-moz-animation-iteration-count:1;-ms-animation-iteration-count:1;-o-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-duration:.2s;-moz-animation-duration:.2s;-ms-animation-duration:.2s;-o-animation-duration:.2s;animation-duration:.2s;-webkit-animation-delay:0s;-moz-animation-delay:0s;-ms-animation-delay:0s;-o-animation-delay:0s;animation-delay:0s;-webkit-animation-timing-function:cubic-bezier(.23,1,.32,1);-moz-animation-timing-function:cubic-bezier(.23,1,.32,1);-ms-animation-timing-function:cubic-bezier(.23,1,.32,1);-o-animation-timing-function:cubic-bezier(.23,1,.32,1);animation-timing-function:cubic-bezier(.23,1,.32,1);-webkit-animation-fill-mode:forwards;-moz-animation-fill-mode:forwards;-ms-animation-fill-mode:forwards;-o-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;backface-visibility:hidden}.next-icon[dir=rtl]:before{transform:rotateY(180deg)}@font-face{font-family:NextIcon;src:url(../console-ui/public/fonts/font_1533967_slipq25tezj.eot);src:url(../console-ui/public/fonts/font_1533967_slipq25tezj.eot?#iefix) format("embedded-opentype"),url(../console-ui/public/fonts/font_1533967_slipq25tezj.woff2) format("woff2"),url(../console-ui/public/fonts/font_1533967_slipq25tezj.woff) format("woff"),url(../console-ui/public/fonts/font_1533967_slipq25tezj.ttf) format("truetype"),url(../console-ui/public/fonts/font_1533967_slipq25tezj.svg#NextIcon) format("svg");font-display:swap}.next-icon{display:inline-block;font-family:NextIcon;font-style:normal;font-weight:400;text-transform:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.next-icon:before{display:inline-block;vertical-align:middle;text-align:center}.next-icon-smile:before{content:""}.next-icon-cry:before{content:""}.next-icon-success:before{content:""}.next-icon-warning:before{content:""}.next-icon-prompt:before{content:""}.next-icon-error:before{content:""}.next-icon-help:before{content:""}.next-icon-clock:before{content:""}.next-icon-success-filling:before{content:""}.next-icon-delete-filling:before{content:""}.next-icon-favorites-filling:before{content:""}.next-icon-add:before{content:""}.next-icon-minus:before{content:""}.next-icon-arrow-up:before{content:""}.next-icon-arrow-down:before{content:""}.next-icon-arrow-left:before{content:""}.next-icon-arrow-right:before{content:""}.next-icon-arrow-double-left:before{content:""}.next-icon-arrow-double-right:before{content:""}.next-icon-switch:before{content:""}.next-icon-sorting:before{content:""}.next-icon-descending:before{content:""}.next-icon-ascending:before{content:""}.next-icon-select:before{content:""}.next-icon-semi-select:before{content:""}.next-icon-search:before{content:""}.next-icon-close:before{content:""}.next-icon-ellipsis:before{content:""}.next-icon-picture:before{content:""}.next-icon-calendar:before{content:""}.next-icon-ashbin:before{content:""}.next-icon-upload:before{content:""}.next-icon-download:before{content:""}.next-icon-set:before{content:""}.next-icon-edit:before{content:""}.next-icon-refresh:before{content:""}.next-icon-filter:before{content:""}.next-icon-attachment:before{content:""}.next-icon-account:before{content:""}.next-icon-email:before{content:""}.next-icon-atm:before{content:""}.next-icon-loading:before{content:"";animation:loadingCircle 1s linear infinite}.next-icon-eye:before{content:""}.next-icon-copy:before{content:""}.next-icon-toggle-left:before{content:""}.next-icon-toggle-right:before{content:""}.next-icon-eye-close:before{content:""}.next-icon-unlock:before{content:""}.next-icon-lock:before{content:""}.next-icon-exit:before{content:""}.next-icon-chart-bar:before{content:""}.next-icon-chart-pie:before{content:""}.next-icon-form:before{content:""}.next-icon-detail:before{content:""}.next-icon-list:before{content:""}.next-icon-dashboard:before{content:""}.next-icon.next-xxs .next-icon-remote,.next-icon.next-xxs:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-icon.next-xxs{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-icon.next-xxs:before{width:16px;font-size:16px}}.next-icon.next-xs .next-icon-remote,.next-icon.next-xs:before{width:12px;font-size:12px;line-height:inherit}.next-icon.next-small .next-icon-remote,.next-icon.next-small:before{width:16px;font-size:16px;line-height:inherit}.next-icon.next-medium .next-icon-remote,.next-icon.next-medium:before{width:20px;font-size:20px;line-height:inherit}.next-icon.next-large .next-icon-remote,.next-icon.next-large:before{width:24px;font-size:24px;line-height:inherit}.next-icon.next-xl .next-icon-remote,.next-icon.next-xl:before{width:32px;font-size:32px;line-height:inherit}.next-icon.next-xxl .next-icon-remote,.next-icon.next-xxl:before{width:48px;font-size:48px;line-height:inherit}.next-icon.next-xxxl .next-icon-remote,.next-icon.next-xxxl:before{width:64px;font-size:64px;line-height:inherit}.next-icon.next-inherit .next-icon-remote,.next-icon.next-inherit:before{width:inherit;font-size:inherit;line-height:inherit}.next-icon .next-icon-remote,.next-icon.next-inherit .next-icon-remote{width:1em;height:1em;vertical-align:middle;fill:currentColor}.next-overlay-wrapper .next-overlay-inner{z-index:1001}.next-overlay-wrapper .next-overlay-backdrop{position:fixed;z-index:1001;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,.3);transition:opacity .3s cubic-bezier(.4,0,.2,1);opacity:0}.next-overlay-wrapper.opened .next-overlay-backdrop{opacity:1}.next-loading-fusion-reactor[dir=rtl]{-webkit-animation-name:nextVectorRouteRTL;-moz-animation-name:nextVectorRouteRTL;-ms-animation-name:nextVectorRouteRTL;-o-animation-name:nextVectorRouteRTL;animation-name:nextVectorRouteRTL}@-webkit-keyframes nextVectorRouteRTL{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}25%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}30%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}50%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}55%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}75%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}80%{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}}@-moz-keyframes nextVectorRouteRTL{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}25%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}30%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}50%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}55%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}75%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}80%{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}}@-ms-keyframes nextVectorRouteRTL{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}25%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}30%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}50%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}55%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}75%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}80%{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}}@-o-keyframes nextVectorRouteRTL{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}25%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}30%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}50%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}55%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}75%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}80%{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}}@keyframes nextVectorRouteRTL{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}25%{-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}30%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}50%{-webkit-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-ms-transform:rotate(-180deg);-o-transform:rotate(-180deg);transform:rotate(-180deg)}55%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}75%{-webkit-transform:rotate(-270deg);-moz-transform:rotate(-270deg);-ms-transform:rotate(-270deg);-o-transform:rotate(-270deg);transform:rotate(-270deg)}80%{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}to{-webkit-transform:rotate(-1turn);-moz-transform:rotate(-1turn);-ms-transform:rotate(-1turn);-o-transform:rotate(-1turn);transform:rotate(-1turn)}}.next-loading{position:relative}.next-loading.next-open{pointer-events:none}.next-loading .next-loading-component{opacity:.7;-webkit-filter:blur(1px);filter:blur(1px);filter:"progid:DXImageTransform.Microsoft.Blur(PixelRadius=1, MakeShadow=false)";position:relative;pointer-events:none}.next-loading-masker{position:absolute;top:0;bottom:0;left:0;right:0;z-index:99;opacity:.2;background:#fff}.next-loading-inline{display:inline-block}.next-loading-tip{display:block;position:absolute;top:50%;left:50%;z-index:4;transform:translate(-50%,-50%);text-align:center}.next-loading-tip-fullscreen{top:inherit;left:inherit;transform:inherit}.next-loading-tip-placeholder{display:none}.next-loading-right-tip .next-loading-indicator{display:inline-block}.next-loading-right-tip .next-loading-tip-content{position:absolute;display:block;top:50%;right:0;transform:translateY(-50%)}.next-loading-right-tip .next-loading-tip-placeholder{display:inline-block;visibility:hidden;margin-left:1em}.next-loading-fusion-reactor{display:inline-block;width:40px;height:40px;position:relative;margin:0;-webkit-animation-duration:5.6s;-moz-animation-duration:5.6s;-ms-animation-duration:5.6s;-o-animation-duration:5.6s;animation-duration:5.6s;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-o-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-timing-function:linear;-moz-animation-timing-function:linear;-ms-animation-timing-function:linear;-o-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-name:nextVectorRoute;-moz-animation-name:nextVectorRoute;-ms-animation-name:nextVectorRoute;-o-animation-name:nextVectorRoute;animation-name:nextVectorRoute}.next-loading-fusion-reactor .next-loading-dot{position:absolute;margin:auto;width:12px;height:12px;border-radius:50%;background:#209bfa;-webkit-animation-timing-function:ease-in-out;-moz-animation-timing-function:ease-in-out;-ms-animation-timing-function:ease-in-out;-o-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-iteration-count:infinite;-moz-animation-iteration-count:infinite;-ms-animation-iteration-count:infinite;-o-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-duration:1.4s;-moz-animation-duration:1.4s;-ms-animation-duration:1.4s;-o-animation-duration:1.4s;animation-duration:1.4s}.next-loading-fusion-reactor .next-loading-dot:first-child{top:0;bottom:0;left:0;-webkit-animation-name:nextVectorDotsX;-moz-animation-name:nextVectorDotsX;-ms-animation-name:nextVectorDotsX;-o-animation-name:nextVectorDotsX;animation-name:nextVectorDotsX}.next-loading-fusion-reactor .next-loading-dot:nth-child(2){left:0;right:0;top:0;opacity:.8;-webkit-animation-name:nextVectorDotsY;-moz-animation-name:nextVectorDotsY;-ms-animation-name:nextVectorDotsY;-o-animation-name:nextVectorDotsY;animation-name:nextVectorDotsY}.next-loading-fusion-reactor .next-loading-dot:nth-child(3){top:0;bottom:0;right:0;opacity:.6;-webkit-animation-name:nextVectorDotsXR;-moz-animation-name:nextVectorDotsXR;-ms-animation-name:nextVectorDotsXR;-o-animation-name:nextVectorDotsXR;animation-name:nextVectorDotsXR}.next-loading-fusion-reactor .next-loading-dot:nth-child(4){left:0;right:0;bottom:0;opacity:.2;-webkit-animation-name:nextVectorDotsYR;-moz-animation-name:nextVectorDotsYR;-ms-animation-name:nextVectorDotsYR;-o-animation-name:nextVectorDotsYR;animation-name:nextVectorDotsYR}.next-loading-medium-fusion-reactor{width:24px;height:24px}.next-loading-medium-fusion-reactor .next-loading-dot{width:8px;height:8px}.next-loading-medium-fusion-reactor .next-loading-dot:first-child{-webkit-animation-name:nextVectorDotsX-medium;-moz-animation-name:nextVectorDotsX-medium;-ms-animation-name:nextVectorDotsX-medium;-o-animation-name:nextVectorDotsX-medium;animation-name:nextVectorDotsX-medium}.next-loading-medium-fusion-reactor .next-loading-dot:nth-child(2){-webkit-animation-name:nextVectorDotsY-medium;-moz-animation-name:nextVectorDotsY-medium;-ms-animation-name:nextVectorDotsY-medium;-o-animation-name:nextVectorDotsY-medium;animation-name:nextVectorDotsY-medium}.next-loading-medium-fusion-reactor .next-loading-dot:nth-child(3){-webkit-animation-name:nextVectorDotsXR-medium;-moz-animation-name:nextVectorDotsXR-medium;-ms-animation-name:nextVectorDotsXR-medium;-o-animation-name:nextVectorDotsXR-medium;animation-name:nextVectorDotsXR-medium}.next-loading-medium-fusion-reactor .next-loading-dot:nth-child(4){-webkit-animation-name:nextVectorDotsYR-medium;-moz-animation-name:nextVectorDotsYR-medium;-ms-animation-name:nextVectorDotsYR-medium;-o-animation-name:nextVectorDotsYR-medium;animation-name:nextVectorDotsYR-medium}@-webkit-keyframes nextVectorRoute{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}25%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}30%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}50%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}55%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}75%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}80%{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}}@-moz-keyframes nextVectorRoute{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}25%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}30%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}50%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}55%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}75%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}80%{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}}@-ms-keyframes nextVectorRoute{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}25%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}30%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}50%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}55%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}75%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}80%{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}}@-o-keyframes nextVectorRoute{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}25%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}30%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}50%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}55%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}75%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}80%{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes nextVectorRoute{0%{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);-ms-transform:rotate(0deg);-o-transform:rotate(0deg);transform:rotate(0deg)}5%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}25%{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}30%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}50%{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}55%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}75%{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}80%{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}to{-webkit-transform:rotate(1turn);-moz-transform:rotate(1turn);-ms-transform:rotate(1turn);-o-transform:rotate(1turn);transform:rotate(1turn)}}@-webkit-keyframes nextVectorDotsYR{25%{bottom:0}45%,50%{bottom:12.8px;height:14.4px;width:14.4px}90%{bottom:0;height:12px;width:12px}}@-moz-keyframes nextVectorDotsYR{25%{bottom:0}45%,50%{bottom:12.8px;height:14.4px;width:14.4px}90%{bottom:0;height:12px;width:12px}}@-ms-keyframes nextVectorDotsYR{25%{bottom:0}45%,50%{bottom:12.8px;height:14.4px;width:14.4px}90%{bottom:0;height:12px;width:12px}}@-o-keyframes nextVectorDotsYR{25%{bottom:0}45%,50%{bottom:12.8px;height:14.4px;width:14.4px}90%{bottom:0;height:12px;width:12px}}@keyframes nextVectorDotsYR{25%{bottom:0}45%,50%{bottom:12.8px;height:14.4px;width:14.4px}90%{bottom:0;height:12px;width:12px}}@-webkit-keyframes nextVectorDotsY{25%{top:0}45%,50%{top:12.8px;height:14.4px;width:14.4px}90%{top:0;height:12px;width:12px}}@-moz-keyframes nextVectorDotsY{25%{top:0}45%,50%{top:12.8px;height:14.4px;width:14.4px}90%{top:0;height:12px;width:12px}}@-ms-keyframes nextVectorDotsY{25%{top:0}45%,50%{top:12.8px;height:14.4px;width:14.4px}90%{top:0;height:12px;width:12px}}@-o-keyframes nextVectorDotsY{25%{top:0}45%,50%{top:12.8px;height:14.4px;width:14.4px}90%{top:0;height:12px;width:12px}}@keyframes nextVectorDotsY{25%{top:0}45%,50%{top:12.8px;height:14.4px;width:14.4px}90%{top:0;height:12px;width:12px}}@-webkit-keyframes nextVectorDotsX{25%{left:0}45%,50%{left:12.8px;width:14.4px;height:14.4px}90%{left:0;height:12px;width:12px}}@-moz-keyframes nextVectorDotsX{25%{left:0}45%,50%{left:12.8px;width:14.4px;height:14.4px}90%{left:0;height:12px;width:12px}}@-ms-keyframes nextVectorDotsX{25%{left:0}45%,50%{left:12.8px;width:14.4px;height:14.4px}90%{left:0;height:12px;width:12px}}@-o-keyframes nextVectorDotsX{25%{left:0}45%,50%{left:12.8px;width:14.4px;height:14.4px}90%{left:0;height:12px;width:12px}}@keyframes nextVectorDotsX{25%{left:0}45%,50%{left:12.8px;width:14.4px;height:14.4px}90%{left:0;height:12px;width:12px}}@-webkit-keyframes nextVectorDotsXR{25%{right:0}45%,50%{right:12.8px;width:14.4px;height:14.4px}90%{right:0;height:12px;width:12px}}@-moz-keyframes nextVectorDotsXR{25%{right:0}45%,50%{right:12.8px;width:14.4px;height:14.4px}90%{right:0;height:12px;width:12px}}@-ms-keyframes nextVectorDotsXR{25%{right:0}45%,50%{right:12.8px;width:14.4px;height:14.4px}90%{right:0;height:12px;width:12px}}@-o-keyframes nextVectorDotsXR{25%{right:0}45%,50%{right:12.8px;width:14.4px;height:14.4px}90%{right:0;height:12px;width:12px}}@keyframes nextVectorDotsXR{25%{right:0}45%,50%{right:12.8px;width:14.4px;height:14.4px}90%{right:0;height:12px;width:12px}}@-webkit-keyframes nextVectorDotsYR-medium{25%{bottom:0}45%,50%{bottom:7.2px;height:9.6px;width:9.6px}90%{bottom:0;height:8px;width:8px}}@-moz-keyframes nextVectorDotsYR-medium{25%{bottom:0}45%,50%{bottom:7.2px;height:9.6px;width:9.6px}90%{bottom:0;height:8px;width:8px}}@-ms-keyframes nextVectorDotsYR-medium{25%{bottom:0}45%,50%{bottom:7.2px;height:9.6px;width:9.6px}90%{bottom:0;height:8px;width:8px}}@-o-keyframes nextVectorDotsYR-medium{25%{bottom:0}45%,50%{bottom:7.2px;height:9.6px;width:9.6px}90%{bottom:0;height:8px;width:8px}}@keyframes nextVectorDotsYR-medium{25%{bottom:0}45%,50%{bottom:7.2px;height:9.6px;width:9.6px}90%{bottom:0;height:8px;width:8px}}@-webkit-keyframes nextVectorDotsY-medium{25%{top:0}45%,50%{top:7.2px;height:9.6px;width:9.6px}90%{top:0;height:8px;width:8px}}@-moz-keyframes nextVectorDotsY-medium{25%{top:0}45%,50%{top:7.2px;height:9.6px;width:9.6px}90%{top:0;height:8px;width:8px}}@-ms-keyframes nextVectorDotsY-medium{25%{top:0}45%,50%{top:7.2px;height:9.6px;width:9.6px}90%{top:0;height:8px;width:8px}}@-o-keyframes nextVectorDotsY-medium{25%{top:0}45%,50%{top:7.2px;height:9.6px;width:9.6px}90%{top:0;height:8px;width:8px}}@keyframes nextVectorDotsY-medium{25%{top:0}45%,50%{top:7.2px;height:9.6px;width:9.6px}90%{top:0;height:8px;width:8px}}@-webkit-keyframes nextVectorDotsX-medium{25%{left:0}45%,50%{left:7.2px;width:9.6px;height:9.6px}90%{left:0;height:8px;width:8px}}@-moz-keyframes nextVectorDotsX-medium{25%{left:0}45%,50%{left:7.2px;width:9.6px;height:9.6px}90%{left:0;height:8px;width:8px}}@-ms-keyframes nextVectorDotsX-medium{25%{left:0}45%,50%{left:7.2px;width:9.6px;height:9.6px}90%{left:0;height:8px;width:8px}}@-o-keyframes nextVectorDotsX-medium{25%{left:0}45%,50%{left:7.2px;width:9.6px;height:9.6px}90%{left:0;height:8px;width:8px}}@keyframes nextVectorDotsX-medium{25%{left:0}45%,50%{left:7.2px;width:9.6px;height:9.6px}90%{left:0;height:8px;width:8px}}@-webkit-keyframes nextVectorDotsXR-medium{25%{right:0}45%,50%{right:7.2px;width:9.6px;height:9.6px}90%{right:0;height:8px;width:8px}}@-moz-keyframes nextVectorDotsXR-medium{25%{right:0}45%,50%{right:7.2px;width:9.6px;height:9.6px}90%{right:0;height:8px;width:8px}}@-ms-keyframes nextVectorDotsXR-medium{25%{right:0}45%,50%{right:7.2px;width:9.6px;height:9.6px}90%{right:0;height:8px;width:8px}}@-o-keyframes nextVectorDotsXR-medium{25%{right:0}45%,50%{right:7.2px;width:9.6px;height:9.6px}90%{right:0;height:8px;width:8px}}@keyframes nextVectorDotsXR-medium{25%{right:0}45%,50%{right:7.2px;width:9.6px;height:9.6px}90%{right:0;height:8px;width:8px}}.next-radio-button-large[dir=rtl]>label:first-child{margin-left:-1px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-left-radius:0;border-bottom-left-radius:0}.next-radio-button-large[dir=rtl]>label:last-child{margin-left:0;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-radio-button-large[dir=rtl] .next-radio-label{height:38px;line-height:38px;font-size:16px}.next-radio-button-medium[dir=rtl]>label:first-child{margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.next-radio-button-medium[dir=rtl]>label:last-child{margin-left:0;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-radio-button-small[dir=rtl]>label:first-child{margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:3px;border-bottom-right-radius:3px}.next-radio-button-small[dir=rtl]>label:last-child{margin-left:0;border-top-right-radius:0;border-bottom-right-radius:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-radio-wrapper[dir=rtl] .next-radio-label{margin-left:0;margin-right:4px}.next-radio-group[dir=rtl] .next-radio-label{margin-right:4px;margin-left:16px}.next-radio-button[dir=rtl]>label .next-radio-label{margin:0}.next-radio-wrapper{outline:0;display:inline-block}.next-radio-wrapper .next-radio{box-sizing:border-box;display:inline-block;vertical-align:middle;position:relative;line-height:1}.next-radio-wrapper .next-radio *,.next-radio-wrapper .next-radio :after,.next-radio-wrapper .next-radio :before{box-sizing:border-box}.next-radio-wrapper .next-radio input[type=radio]{opacity:0;position:absolute;vertical-align:middle;top:0;left:0;width:16px;height:16px;margin:0;cursor:pointer}.next-radio-wrapper .next-radio-inner{display:block;width:16px;height:16px;background:#fff;border-radius:50%;border:1px solid #ddd;transition:all .1s linear;box-shadow:none}.next-radio-wrapper .next-radio-inner:after{transform:scale(0);position:absolute;border-radius:50%;top:50%;margin-top:-2px;left:50%;margin-left:-2px;background:#fff;content:"";transition:all .1s linear}.next-radio-wrapper.checked .next-radio-inner{border-color:#209bfa;background:#209bfa}.next-radio-wrapper.checked .next-radio-inner:after{width:4px;height:4px;font-weight:700;background:#fff;transform:scale(1)}.next-radio-wrapper.checked.hovered .next-radio-inner,.next-radio-wrapper.checked:hover .next-radio-inner{border-color:transparent}.next-radio-wrapper.disabled input[type=radio]{cursor:not-allowed}.next-radio-wrapper.disabled .next-radio-inner{border-color:#eee;background:#fafafa}.next-radio-wrapper.disabled .next-radio-inner:after{background:#ccc}.next-radio-wrapper.disabled .next-radio-inner.hovered,.next-radio-wrapper.disabled .next-radio-inner:hover{border-color:#eee}.next-radio-wrapper.disabled.checked .next-radio-inner{border-color:#eee;background:#fafafa}.next-radio-wrapper.disabled.checked .next-radio-inner:after{background:#ccc}.next-radio-wrapper.disabled .next-radio-label{color:#ccc}.next-radio-wrapper:not(.disabled).hovered .next-radio-inner,.next-radio-wrapper:not(.disabled):hover .next-radio-inner{border-color:#209bfa;background-color:#add9ff}.next-radio-wrapper:not(.disabled).hovered .next-radio-label,.next-radio-wrapper:not(.disabled):hover .next-radio-label{cursor:pointer}.next-radio-wrapper.checked:not(.disabled).hovered .next-radio-inner,.next-radio-wrapper.checked:not(.disabled):hover .next-radio-inner{border-color:transparent;background:#1274e7}.next-radio-wrapper.checked:not(.disabled).hovered .next-radio-inner:after,.next-radio-wrapper.checked:not(.disabled):hover .next-radio-inner:after{background:#fff}.next-radio-button .next-radio,.next-radio-button input[type=radio]{width:0;height:0}.next-radio-button>label{display:inline-block;box-sizing:border-box;position:relative;z-index:1;margin:0 0 0 -1px;border:1px solid #ddd;background-color:#fff;transition:all .1s linear;vertical-align:middle}.next-radio-button>label .next-radio-label{display:block;color:#333;margin:0;transition:all .1s linear}.next-radio-button>label.hovered,.next-radio-button>label:hover{z-index:10;border-color:#ccc;background-color:#f9f9f9}.next-radio-button>label.hovered .next-radio-label,.next-radio-button>label:hover .next-radio-label{color:#333}.next-radio-button>label.checked{z-index:11;border-color:#209bfa;background-color:#fff}.next-radio-button>label.checked .next-radio-label{color:#209bfa}.next-radio-button>label.disabled{z-index:0;cursor:not-allowed;border-color:#eee;background-color:#fafafa}.next-radio-button>label.disabled .next-radio-label{color:#ccc}.next-radio-button>label.checked.disabled{z-index:0;border-color:#eee;background-color:#f9f9f9}.next-radio-button>label.checked.disabled .next-radio-label{color:#ccc}.next-radio-button-large>label{padding:0 8px;height:40px;line-height:40px}.next-radio-button-large>label:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-radio-button-large>label:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.next-radio-button-large .next-radio-label{height:38px;line-height:38px;font-size:16px}.next-radio-button-medium>label{padding:0 8px;height:32px;line-height:32px}.next-radio-button-medium>label:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-radio-button-medium>label:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.next-radio-button-medium .next-radio-label{height:30px;line-height:30px;font-size:14px}.next-radio-button-small>label{padding:0 8px;height:20px;line-height:20px}.next-radio-button-small>label:first-child{margin-left:0;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-radio-button-small>label:last-child{border-top-right-radius:3px;border-bottom-right-radius:3px}.next-radio-button-small .next-radio-label{height:18px;line-height:18px;font-size:12px}.next-radio-single-input input[type=radio]{opacity:0;position:absolute;top:0;left:0;margin:0}.next-radio-group{display:inline-block}.next-radio-group .next-radio-wrapper{margin-right:12px}.next-radio-group .next-radio-wrapper:last-child{margin-right:0}.next-radio-group .next-radio-label{color:#333}.next-radio-group.disabled .next-radio-label{color:#ccc}.next-radio-group.next-radio-button .next-radio-wrapper{margin-right:0}.next-radio-group-ver .next-radio-wrapper{display:block;margin-bottom:8px}.next-radio-label{margin:0 4px;font-size:14px;vertical-align:middle;line-height:1;color:#333}@-moz-document url-prefix(){.next-radio{margin-top:-1px}@supports(animation:calc(0s)){.next-radio{margin-top:-3px}}}.next-badge{position:relative;display:inline-block;vertical-align:middle;line-height:1}.next-badge,.next-badge *,.next-badge :after,.next-badge :before{box-sizing:border-box}.next-badge .next-badge-count{color:#fff;background:#d23c26;text-align:center;white-space:nowrap;border-radius:8px;position:absolute;width:auto;height:16px;min-width:16px;padding:0 4px;font-size:12px;line-height:16px;transform:translateX(-50%);top:-.5em;border:0 solid #fff}.next-badge .next-badge-count a,.next-badge .next-badge-count a:hover{color:#fff}.next-badge .next-badge-dot{color:#fff;background:#d23c26;text-align:center;white-space:nowrap;border-radius:8px;position:absolute;width:8px;height:8px;min-width:8px;padding:0;font-size:1px;line-height:1;transform:translateX(-50%);top:-.5em}.next-badge .next-badge-dot a,.next-badge .next-badge-dot a:hover{color:#fff}.next-badge .next-badge-custom{line-height:1.166667;white-space:nowrap;font-size:12px;padding-left:4px;padding-right:4px;border-radius:3px;transform:translateX(-50%)}.next-badge .next-badge-custom>*{line-height:1}.next-badge .next-badge-custom>.next-icon:before,.next-badge .next-badge-custom>i:before{font-size:inherit;width:auto;vertical-align:top}.next-badge .next-badge-scroll-number{position:absolute;top:-4px;z-index:10;overflow:hidden;transform-origin:left center}.next-badge-scroll-number-only{position:relative;display:inline-block;transition:transform .1s linear,-webkit-transform .1s linear;min-width:8px}.next-badge-scroll-number-only span{display:block;height:16px;line-height:16px;font-size:12px}.next-badge-not-a-wrapper .next-badge-count,.next-badge-not-a-wrapper .next-badge-custom,.next-badge-not-a-wrapper .next-badge-dot{position:relative;display:block;top:auto;transform:translateX(0)}.next-badge-list-wrapper{margin-left:0}.next-badge-list-wrapper li{margin-bottom:0;list-style:none}.next-badge[dir=rtl] .next-badge-custom{padding-right:4px;padding-left:4px}.next-badge[dir=rtl] .next-badge-scroll-number{left:0;transform-origin:right center}.next-balloon{position:absolute;top:0;max-width:300px;border-style:solid;border-radius:3px;font-size:14px;font-weight:400;word-wrap:break-all;word-wrap:break-word;z-index:0}.next-balloon,.next-balloon *,.next-balloon :after,.next-balloon :before{box-sizing:border-box}.next-balloon:focus,.next-balloon :focus{outline:0}.next-balloon-title{margin-bottom:8px;font-size:16px;font-weight:700}.next-balloon-title.next-balloon-closable{padding:0 40px 0 0}.next-balloon-title.next-balloon-closable .next-balloon-close{top:-1px;transform:translateY(16px);right:16px}.next-balloon-primary{color:#333;border-color:#209bfa;background-color:#add9ff;box-shadow:0 1px 3px 0 rgba(0,0,0,.12);border-width:1px}.next-balloon-primary .next-balloon-close{position:absolute;top:-1px;transform:translateY(15px);right:12px;font-size:16px;cursor:pointer;color:#999}.next-balloon-primary .next-balloon-close .next-icon{width:16px;height:16px;line-height:1em}.next-balloon-primary .next-balloon-close .next-icon:before{width:16px;height:16px;font-size:16px;line-height:1em}.next-balloon-primary .next-balloon-close :hover{color:#333}.next-balloon-primary:after{position:absolute;width:12px;height:12px;content:"";transform:rotate(45deg);box-sizing:content-box!important;border:1px solid #209bfa;background-color:#add9ff;z-index:-1}.next-balloon-primary.next-balloon-top:after{top:-7px;left:calc(50% - 7px);border-right:none;border-bottom:none}.next-balloon-primary.next-balloon-right:after{top:calc(50% - 7px);right:-7px;border-left:none;border-bottom:none}.next-balloon-primary.next-balloon-bottom:after{bottom:-7px;left:calc(50% - 7px);border-top:none;border-left:none}.next-balloon-primary.next-balloon-left:after{top:calc(50% - 7px);left:-7px;border-top:none;border-right:none}.next-balloon-primary.next-balloon-left-top:after{top:12px;left:-7px;border-top:none;border-right:none}.next-balloon-primary.next-balloon-left-bottom:after{bottom:12px;left:-7px;border-top:none;border-right:none}.next-balloon-primary.next-balloon-right-top:after{top:12px;right:-7px;border-bottom:none;border-left:none}.next-balloon-primary.next-balloon-right-bottom:after{right:-7px;bottom:12px;border-bottom:none;border-left:none}.next-balloon-primary.next-balloon-top-left:after{top:-7px;left:12px;border-right:none;border-bottom:none}.next-balloon-primary.next-balloon-top-right:after{top:-7px;right:12px;border-right:none;border-bottom:none}.next-balloon-primary.next-balloon-bottom-left:after{bottom:-7px;left:12px;border-top:none;border-left:none}.next-balloon-primary.next-balloon-bottom-right:after{right:12px;bottom:-7px;border-top:none;border-left:none}.next-balloon-normal{color:#333;border-color:#e6e6e6;background-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-width:1px}.next-balloon-normal .next-balloon-close{position:absolute;top:-1px;transform:translateY(15px);right:12px;font-size:16px;cursor:pointer;color:#999}.next-balloon-normal .next-balloon-close .next-icon{width:16px;height:16px;line-height:1em}.next-balloon-normal .next-balloon-close .next-icon:before{width:16px;height:16px;font-size:16px;line-height:1em}.next-balloon-normal .next-balloon-close :hover{color:#666}.next-balloon-normal:after{position:absolute;width:12px;height:12px;content:"";transform:rotate(45deg);box-sizing:content-box!important;border:1px solid #e6e6e6;background-color:#fff;z-index:-1}.next-balloon-normal.next-balloon-top:after{top:-7px;left:calc(50% - 7px);border-right:none;border-bottom:none}.next-balloon-normal.next-balloon-right:after{top:calc(50% - 7px);right:-7px;border-left:none;border-bottom:none}.next-balloon-normal.next-balloon-bottom:after{bottom:-7px;left:calc(50% - 7px);border-top:none;border-left:none}.next-balloon-normal.next-balloon-left:after{top:calc(50% - 7px);left:-7px;border-top:none;border-right:none}.next-balloon-normal.next-balloon-left-top:after{top:12px;left:-7px;border-top:none;border-right:none}.next-balloon-normal.next-balloon-left-bottom:after{bottom:12px;left:-7px;border-top:none;border-right:none}.next-balloon-normal.next-balloon-right-top:after{top:12px;right:-7px;border-bottom:none;border-left:none}.next-balloon-normal.next-balloon-right-bottom:after{right:-7px;bottom:12px;border-bottom:none;border-left:none}.next-balloon-normal.next-balloon-top-left:after{top:-7px;left:12px;border-right:none;border-bottom:none}.next-balloon-normal.next-balloon-top-right:after{top:-7px;right:12px;border-right:none;border-bottom:none}.next-balloon-normal.next-balloon-bottom-left:after{bottom:-7px;left:12px;border-top:none;border-left:none}.next-balloon-normal.next-balloon-bottom-right:after{right:12px;bottom:-7px;border-top:none;border-left:none}.next-balloon.visible{display:block}.next-balloon.hidden{display:none}.next-balloon-medium{padding:16px}.next-balloon-closable{padding:16px 40px 16px 16px}.next-balloon-tooltip{box-sizing:border-box;position:absolute;top:0;max-width:300px;border-radius:3px;font-size:14px;font-weight:400;z-index:0;word-wrap:break-all;word-wrap:break-word;color:#fafafa;background-color:#333;box-shadow:none;border:1px solid transparent}.next-balloon-tooltip *,.next-balloon-tooltip :after,.next-balloon-tooltip :before{box-sizing:border-box}.next-balloon-tooltip .next-balloon-arrow{position:absolute;display:block;width:24px;height:24px;overflow:hidden;background:0 0;pointer-events:none}.next-balloon-tooltip .next-balloon-arrow .next-balloon-arrow-content{content:"";position:absolute;top:0;right:0;bottom:0;left:0;display:block;width:12px;height:12px;margin:auto;background-color:#333;border:1px solid transparent;pointer-events:auto}.next-balloon-tooltip-top .next-balloon-arrow{top:-24px;left:calc(50% - 12px)}.next-balloon-tooltip-top .next-balloon-arrow .next-balloon-arrow-content{transform:translateY(12px) rotate(45deg)}.next-balloon-tooltip-right .next-balloon-arrow{top:calc(50% - 12px);right:-24px}.next-balloon-tooltip-right .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(-12px) rotate(45deg)}.next-balloon-tooltip-bottom .next-balloon-arrow{left:calc(50% - 12px);bottom:-24px}.next-balloon-tooltip-bottom .next-balloon-arrow .next-balloon-arrow-content{transform:translateY(-12px) rotate(45deg)}.next-balloon-tooltip-left .next-balloon-arrow{top:calc(50% - 12px);left:-24px}.next-balloon-tooltip-left .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(12px) rotate(45deg)}.next-balloon-tooltip-left-top .next-balloon-arrow{top:6px;left:-24px}.next-balloon-tooltip-left-top .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(12px) rotate(45deg)}.next-balloon-tooltip-left-bottom .next-balloon-arrow{bottom:6px;left:-24px}.next-balloon-tooltip-left-bottom .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(12px) rotate(45deg)}.next-balloon-tooltip-right-top .next-balloon-arrow{top:6px;right:-24px}.next-balloon-tooltip-right-top .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(-12px) rotate(45deg)}.next-balloon-tooltip-right-bottom .next-balloon-arrow{bottom:6px;right:-24px}.next-balloon-tooltip-right-bottom .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(-12px) rotate(45deg)}.next-balloon-tooltip-top-left .next-balloon-arrow{left:6px;top:-24px}.next-balloon-tooltip-top-left .next-balloon-arrow .next-balloon-arrow-content{transform:translateY(12px) rotate(45deg)}.next-balloon-tooltip-top-right .next-balloon-arrow{right:6px;top:-24px}.next-balloon-tooltip-top-right .next-balloon-arrow .next-balloon-arrow-content{transform:translateY(12px) rotate(45deg)}.next-balloon-tooltip-bottom-left .next-balloon-arrow{left:6px;bottom:-24px}.next-balloon-tooltip-bottom-left .next-balloon-arrow .next-balloon-arrow-content{transform:translateY(-12px) rotate(45deg)}.next-balloon-tooltip-bottom-right .next-balloon-arrow{right:6px;bottom:-24px}.next-balloon-tooltip-bottom-right .next-balloon-arrow .next-balloon-arrow-content{transform:translateY(-12px) rotate(45deg)}.next-balloon-tooltip.visible{display:block}.next-balloon-tooltip.hidden{display:none}.next-balloon-tooltip-medium{padding:8px}.next-balloon[dir=rtl].next-balloon-primary .next-balloon-close{left:12px;right:auto}.next-balloon[dir=rtl].next-balloon-primary.next-balloon-right:after{left:-7px;right:auto;border-right:none;border-top:none;border-left:inherit;border-bottom:inherit}.next-balloon[dir=rtl].next-balloon-primary.next-balloon-left-bottom:after,.next-balloon[dir=rtl].next-balloon-primary.next-balloon-left-top:after,.next-balloon[dir=rtl].next-balloon-primary.next-balloon-left:after{right:-7px;left:auto;border-left:none;border-bottom:none;border-right:inherit;border-top:inherit}.next-balloon[dir=rtl].next-balloon-primary.next-balloon-right-bottom:after,.next-balloon[dir=rtl].next-balloon-primary.next-balloon-right-top:after{left:-7px;right:auto;border-right:none;border-top:none;border-bottom:inherit;border-left:inherit}.next-balloon[dir=rtl].next-balloon-primary.next-balloon-top-left:after{right:12px;left:auto}.next-balloon[dir=rtl].next-balloon-primary.next-balloon-top-right:after{right:auto;left:12px}.next-balloon[dir=rtl].next-balloon-primary.next-balloon-bottom-left:after{right:12px;left:auto}.next-balloon[dir=rtl].next-balloon-normal .next-balloon-close,.next-balloon[dir=rtl].next-balloon-primary.next-balloon-bottom-right:after{left:12px;right:auto}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-right:after{left:-7px;right:auto;border-right:none;border-top:none;border-left:inherit;border-bottom:inherit}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-left-bottom:after,.next-balloon[dir=rtl].next-balloon-normal.next-balloon-left-top:after,.next-balloon[dir=rtl].next-balloon-normal.next-balloon-left:after{right:-7px;left:auto;border-left:none;border-bottom:none;border-right:inherit;border-top:inherit}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-right-bottom:after,.next-balloon[dir=rtl].next-balloon-normal.next-balloon-right-top:after{left:-7px;right:auto;border-right:none;border-top:none;border-bottom:inherit;border-left:inherit}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-top-left:after{right:12px;left:auto}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-top-right:after{right:auto;left:12px}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-bottom-left:after{right:12px;left:auto}.next-balloon[dir=rtl].next-balloon-normal.next-balloon-bottom-right:after{left:12px;right:auto}.next-balloon[dir=rtl].next-balloon-closable{padding:16px 16px 16px 40px}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-right .next-balloon-arrow{left:-24px;right:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-right .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(12px) rotate(45deg)}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-left .next-balloon-arrow{right:-24px;left:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-left .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(-12px) rotate(45deg)}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-left-top .next-balloon-arrow{right:-24px;left:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-left-top .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(-12px) rotate(45deg)}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-left-bottom .next-balloon-arrow{right:-24px;left:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-left-bottom .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(-12px) rotate(45deg)}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-right-top .next-balloon-arrow{left:-24px;right:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-right-top .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(12px) rotate(45deg)}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-right-bottom .next-balloon-arrow{left:-24px;right:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-right-bottom .next-balloon-arrow .next-balloon-arrow-content{transform:translateX(12px) rotate(45deg)}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-top-left .next-balloon-arrow{right:10px;left:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-top-right .next-balloon-arrow{left:10px;right:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-bottom-left .next-balloon-arrow{right:10px;left:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-bottom-right .next-balloon-arrow{left:10px;right:auto}.next-balloon-tooltip[dir=rtl].next-balloon-tooltip-medium{padding:8px}.next-menu[dir=rtl] .next-menu-item-helper{float:left}.next-menu[dir=rtl] .next-menu-item .next-checkbox,.next-menu[dir=rtl] .next-menu-item .next-radio{margin-left:4px;margin-right:0}.next-menu[dir=rtl] .next-menu-hoz-right{float:left}.next-menu[dir=rtl] .next-menu-hoz-icon-arrow.next-icon{left:6px;right:auto}.next-menu[dir=rtl] .next-menu-icon-selected.next-icon{margin-left:0;margin-right:-18px}.next-menu[dir=rtl] .next-menu-icon-selected.next-icon .next-icon-remote,.next-menu[dir=rtl] .next-menu-icon-selected.next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-menu[dir=rtl] .next-menu-icon-selected.next-icon.next-menu-icon-right{right:auto;left:4px}.next-menu[dir=rtl] .next-menu-icon-arrow.next-icon{left:10px;right:auto}.next-menu{position:relative;min-width:100px;margin:0;list-style:none;border:1px solid #e6e6e6;border-radius:3px;box-shadow:none;background:#fff;line-height:32px;font-size:14px;animation-duration:.3s;animation-timing-function:ease}.next-menu,.next-menu *,.next-menu :after,.next-menu :before{box-sizing:border-box}.next-menu:focus,.next-menu :focus{outline:0}.next-menu-spacing-lr{padding:0}.next-menu-spacing-lr.next-menu-outside>.next-menu{height:100%;overflow-y:auto}.next-menu-spacing-tb{padding:0}.next-menu.next-ver{padding:8px 0}.next-menu.next-ver .next-menu-item{padding:0 20px}.next-menu.next-hoz{padding:8px 0}.next-menu.next-hoz .next-menu-item{padding:0 20px}.next-menu-embeddable,.next-menu-embeddable .next-menu-item.next-disabled,.next-menu-embeddable .next-menu-item.next-disabled .next-menu-item-text>a{background:transparent;border:none}.next-menu-embeddable{box-shadow:none}.next-menu-embeddable .next-menu-item-inner{height:100%}.next-menu-content{position:relative}.next-menu-content,.next-menu-sub-menu{padding:0;margin:0;list-style:none}.next-menu-sub-menu.next-expand-enter{overflow:hidden}.next-menu-sub-menu.next-expand-enter-active{transition:height .3s ease}.next-menu-sub-menu.next-expand-leave{overflow:hidden}.next-menu-sub-menu.next-expand-leave-active{transition:height .3s ease}.next-menu-item{position:relative;transition:background .1s linear;color:#333;cursor:pointer}.next-menu-item-helper{float:right;color:#999;font-style:normal;font-size:14px}.next-menu-item .next-checkbox,.next-menu-item .next-radio{margin-right:4px}.next-menu-item.next-selected{color:#333;background-color:#fff;border-radius:0}.next-menu-item.next-selected .next-menu-icon-arrow{color:#666}.next-menu-item.next-selected .next-menu-icon-selected{color:#209bfa}.next-menu-item.next-disabled,.next-menu-item.next-disabled .next-menu-item-text>a{color:#ccc;background-color:#fff;border-radius:0;cursor:not-allowed}.next-menu-item.next-disabled .next-menu-icon-arrow,.next-menu-item.next-disabled .next-menu-icon-selected,.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-arrow,.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-selected{color:#ccc}.next-menu-item:not(.next-disabled).next-focused,.next-menu-item:not(.next-disabled).next-selected.next-focused,.next-menu-item:not(.next-disabled).next-selected.next-focused:hover,.next-menu-item:not(.next-disabled).next-selected:focus,.next-menu-item:not(.next-disabled).next-selected:focus:hover,.next-menu-item:not(.next-disabled).next-selected:hover,.next-menu-item:not(.next-disabled):hover{color:#333;background-color:#f9f9f9;border-radius:0}.next-menu-item:not(.next-disabled).next-focused .next-menu-icon-arrow,.next-menu-item:not(.next-disabled).next-selected.next-focused .next-menu-icon-arrow,.next-menu-item:not(.next-disabled).next-selected.next-focused:hover .next-menu-icon-arrow,.next-menu-item:not(.next-disabled).next-selected:focus .next-menu-icon-arrow,.next-menu-item:not(.next-disabled).next-selected:focus:hover .next-menu-icon-arrow,.next-menu-item:not(.next-disabled).next-selected:hover .next-menu-icon-arrow,.next-menu-item:not(.next-disabled):hover .next-menu-icon-arrow{color:#333}.next-menu-item:not(.next-disabled).next-focused .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected.next-focused .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected.next-focused:hover .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected:focus .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected:focus:hover .next-menu-icon-selected,.next-menu-item:not(.next-disabled).next-selected:hover .next-menu-icon-selected,.next-menu-item:not(.next-disabled):hover .next-menu-icon-selected{color:#209bfa}.next-menu-item-inner{height:32px;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.next-menu-item .next-menu-item-text{vertical-align:middle}.next-menu-item .next-menu-item-text>a{display:inline-block;text-decoration:none;color:#333}.next-menu-item .next-menu-item-text>a:before{position:absolute;background-color:transparent;top:0;left:0;bottom:0;right:0;content:""}.next-menu.next-hoz{padding:0}.next-menu.next-hoz.next-menu-nowrap{overflow:hidden;white-space:nowrap}.next-menu.next-hoz.next-menu-nowrap .next-menu-more{text-align:center}.next-menu.next-hoz .next-menu-content>.next-menu-item,.next-menu.next-hoz>.next-menu-item,.next-menu.next-hoz>.next-menu-sub-menu-wrapper{display:inline-block;vertical-align:top}.next-menu.next-hoz .next-menu-content,.next-menu.next-hoz .next-menu-footer,.next-menu.next-hoz .next-menu-header{display:inline-block}.next-menu-hoz-right{float:right}.next-menu-group-label{padding:0 12px;color:#999}.next-menu-divider{margin:8px 12px;border-bottom:1px solid #eee}.next-menu .next-menu-icon-selected.next-icon{position:absolute;top:0;margin-left:-16px}.next-menu .next-menu-icon-selected.next-icon .next-icon-remote,.next-menu .next-menu-icon-selected.next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-menu .next-menu-icon-selected.next-icon.next-menu-icon-right{right:4px}.next-menu .next-menu-symbol-icon-selected.next-menu-icon-selected:before{content:""}.next-menu .next-menu-icon-arrow.next-icon{position:absolute;top:0;right:10px;color:#666;transition:all .1s linear}.next-menu .next-menu-icon-arrow.next-icon .next-icon-remote,.next-menu .next-menu-icon-arrow.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-menu .next-menu-icon-arrow-down:before{content:""}.next-menu .next-menu-icon-arrow-down.next-open{transform:rotate(180deg)}.next-menu .next-menu-icon-arrow-down.next-open .next-icon-remote,.next-menu .next-menu-icon-arrow-down.next-open:before{width:20px;font-size:20px;line-height:inherit}.next-menu .next-menu-symbol-popupfold:before{content:""}.next-menu .next-menu-icon-arrow-right.next-open{transform:rotate(-90deg)}.next-menu .next-menu-icon-arrow-right.next-open .next-icon-remote,.next-menu .next-menu-icon-arrow-right.next-open:before{width:20px;font-size:20px;line-height:inherit}.next-menu .next-menu-hoz-icon-arrow.next-icon{position:absolute;top:0;right:6px;color:#666;transition:all .1s linear}.next-menu .next-menu-hoz-icon-arrow.next-icon .next-icon-remote,.next-menu .next-menu-hoz-icon-arrow.next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-menu .next-menu-hoz-icon-arrow.next-icon:before{content:""}.next-menu-unfold-icon:before{content:""}.next-menu .next-menu-hoz-icon-arrow.next-open{transform:rotate(180deg)}.next-menu .next-menu-hoz-icon-arrow.next-open .next-icon-remote,.next-menu .next-menu-hoz-icon-arrow.next-open:before{width:12px;font-size:12px;line-height:inherit}.next-menu.next-context{line-height:24px}.next-menu.next-context .next-menu-item-inner{height:24px}.next-breadcrumb{display:block;margin:0;padding:0;white-space:nowrap;height:16px;line-height:16px}.next-breadcrumb .next-breadcrumb-item{display:inline-block}.next-breadcrumb .next-breadcrumb-item .next-breadcrumb-text{display:inline-block;text-decoration:none;text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:all .1s linear}.next-breadcrumb .next-breadcrumb-item .next-breadcrumb-text>b{font-weight:400}.next-breadcrumb .next-breadcrumb-item .next-breadcrumb-separator{display:inline-block;vertical-align:top}.next-breadcrumb .next-breadcrumb-text{height:16px;min-width:16px;font-size:12px;line-height:16px}.next-breadcrumb .next-breadcrumb-separator{height:16px;margin:0 8px;font-size:16px;line-height:16px}.next-breadcrumb .next-breadcrumb-separator .next-icon:before{display:block}.next-breadcrumb .next-breadcrumb-separator .next-icon .next-icon-remote,.next-breadcrumb .next-breadcrumb-separator .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-breadcrumb .next-breadcrumb-text-ellipsis{font-size:12px}.next-breadcrumb .next-breadcrumb-text{color:#666}.next-breadcrumb .next-breadcrumb-text>b{color:#209bfa}.next-breadcrumb .next-breadcrumb-text>a{color:#666;text-decoration:none;text-align:center}.next-breadcrumb .next-breadcrumb-text.activated,.next-breadcrumb .next-breadcrumb-text.activated>a{color:#333;font-weight:700}.next-breadcrumb .next-breadcrumb-text-ellipsis{color:#666;cursor:default}.next-breadcrumb .next-breadcrumb-text-ellipsis-clickable{color:#666;cursor:pointer}.next-breadcrumb .next-breadcrumb-separator{color:#999}.next-breadcrumb .next-breadcrumb-text:not(.next-breadcrumb-text-ellipsis):hover>a,.next-breadcrumb a.next-breadcrumb-text.activated:hover>a,.next-breadcrumb a.next-breadcrumb-text:not(.next-breadcrumb-text-ellipsis):hover,.next-breadcrumb a.next-breadcrumb-text:not(.next-breadcrumb-text-ellipsis):hover>b{color:#209bfa}.next-breadcrumb a.next-breadcrumb-text.activated:hover{color:#209bfa;font-weight:700}.next-breadcrumb-icon-sep:before{content:""}.next-breadcrumb-dropdown-wrapper{padding:4px 0}.next-btn,.next-btn *,.next-btn :after,.next-btn :before{box-sizing:border-box}.next-btn::-moz-focus-inner{border:0;padding:0}.next-btn,.next-btn:active,.next-btn:focus,.next-btn:hover{outline:0}@keyframes loadingCircle{0%{transform-origin:50% 50%;transform:rotate(0deg)}to{transform-origin:50% 50%;transform:rotate(1turn)}}.next-btn{position:relative;display:inline-block;box-shadow:none;text-decoration:none;text-align:center;text-transform:none;white-space:nowrap;vertical-align:middle;user-select:none;transition:all .1s linear;line-height:1;cursor:pointer}.next-btn:after{text-align:center;position:absolute;opacity:0;visibility:hidden;transition:opacity .1s linear}.next-btn:before{content:"";height:100%;width:0}.next-btn .next-icon,.next-btn:before{display:inline-block;vertical-align:middle}.next-btn .next-icon{font-size:0}.next-btn>.next-btn-helper,.next-btn>div,.next-btn>span{display:inline-block;vertical-align:middle}.next-btn>.next-btn-helper{text-decoration:inherit}.next-btn.hover,.next-btn:hover{box-shadow:none}.next-btn.next-small{border-radius:3px;padding:0 16px;height:24px;font-size:12px;border-width:1px}.next-btn.next-small>.next-btn-icon.next-icon-first{transform:scale(1);margin-left:0;margin-right:4px}.next-btn.next-small>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-small>.next-btn-icon.next-icon-first:before{width:12px;font-size:12px;line-height:inherit}.next-btn.next-small>.next-btn-icon.next-icon-last{transform:scale(1);margin-left:4px;margin-right:0}.next-btn.next-small>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-small>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px;line-height:inherit}.next-btn.next-small>.next-btn-icon.next-icon-alone{transform:scale(1)}.next-btn.next-small>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn.next-small>.next-btn-icon.next-icon-alone:before{width:12px;font-size:12px;line-height:inherit}.next-btn.next-small>.next-btn-icon-size{margin-right:4px}.next-btn.next-small.next-btn-loading:before{width:12px;height:12px;font-size:12px;line-height:12px;left:16px;top:50%;text-align:center;margin-right:4px}.next-btn.next-small.next-btn-loading>.next-icon{display:none}.next-btn.next-small>.next-btn-custom-loading-icon{opacity:0;width:0}.next-btn.next-small>.next-btn-custom-loading-icon.show{width:12px;margin-right:4px;opacity:1;transition:all .1s linear}.next-btn.next-medium{border-radius:3px;padding:0 20px;height:32px;font-size:14px;border-width:1px}.next-btn.next-medium>.next-btn-icon.next-icon-first{transform:scale(1);margin-left:0;margin-right:4px}.next-btn.next-medium>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-medium>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-medium>.next-btn-icon.next-icon-last{transform:scale(1);margin-left:4px;margin-right:0}.next-btn.next-medium>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-medium>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-medium>.next-btn-icon.next-icon-alone{transform:scale(1)}.next-btn.next-medium>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn.next-medium>.next-btn-icon.next-icon-alone:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-medium>.next-btn-icon-size{margin-right:4px}.next-btn.next-medium.next-btn-loading:before{width:20px;height:20px;font-size:20px;line-height:20px;left:20px;top:50%;text-align:center;margin-right:4px}.next-btn.next-medium.next-btn-loading>.next-icon{display:none}.next-btn.next-medium>.next-btn-custom-loading-icon{opacity:0;width:0}.next-btn.next-medium>.next-btn-custom-loading-icon.show{width:20px;margin-right:4px;opacity:1;transition:all .1s linear}.next-btn.next-large{border-radius:3px;padding:0 24px;height:40px;font-size:16px;border-width:1px}.next-btn.next-large>.next-btn-icon.next-icon-first{transform:scale(1);margin-left:0;margin-right:4px}.next-btn.next-large>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-large>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-large>.next-btn-icon.next-icon-last{transform:scale(1);margin-left:4px;margin-right:0}.next-btn.next-large>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-large>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-large>.next-btn-icon.next-icon-alone{transform:scale(1)}.next-btn.next-large>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn.next-large>.next-btn-icon.next-icon-alone:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-large>.next-btn-icon-size{margin-right:4px}.next-btn.next-large.next-btn-loading:before{width:20px;height:20px;font-size:20px;line-height:20px;left:24px;top:50%;text-align:center;margin-right:4px}.next-btn.next-large.next-btn-loading>.next-icon{display:none}.next-btn.next-large>.next-btn-custom-loading-icon{opacity:0;width:0}.next-btn.next-large>.next-btn-custom-loading-icon.show{width:20px;margin-right:4px;opacity:1;transition:all .1s linear}.next-btn.next-btn-normal{border-style:solid;background:#fff;border-color:#ddd}.next-btn.next-btn-normal,.next-btn.next-btn-normal.visited,.next-btn.next-btn-normal:link,.next-btn.next-btn-normal:visited{color:#333}.next-btn.next-btn-normal.active,.next-btn.next-btn-normal.hover,.next-btn.next-btn-normal:active,.next-btn.next-btn-normal:focus,.next-btn.next-btn-normal:hover{color:#333;background:#f9f9f9;border-color:#ccc;text-decoration:none}.next-btn.next-btn-primary{border-style:solid;background:#209bfa;border-color:transparent}.next-btn.next-btn-primary,.next-btn.next-btn-primary.visited,.next-btn.next-btn-primary:link,.next-btn.next-btn-primary:visited{color:#fff}.next-btn.next-btn-primary.active,.next-btn.next-btn-primary.hover,.next-btn.next-btn-primary:active,.next-btn.next-btn-primary:focus,.next-btn.next-btn-primary:hover{color:#fff;background:#1274e7;border-color:transparent;text-decoration:none}.next-btn.next-btn-secondary{border-style:solid;background:#fff;border-color:#209bfa}.next-btn.next-btn-secondary,.next-btn.next-btn-secondary.visited,.next-btn.next-btn-secondary:link,.next-btn.next-btn-secondary:visited{color:#209bfa}.next-btn.next-btn-secondary.active,.next-btn.next-btn-secondary.hover,.next-btn.next-btn-secondary:active,.next-btn.next-btn-secondary:focus,.next-btn.next-btn-secondary:hover{color:#fff;background:#1274e7;border-color:#1274e7;text-decoration:none}.next-btn.disabled,.next-btn[disabled]{cursor:not-allowed}.next-btn.disabled.next-btn-normal,.next-btn[disabled].next-btn-normal{background:#fafafa;border-color:#eee}.next-btn.disabled.next-btn-normal,.next-btn.disabled.next-btn-normal.visited,.next-btn.disabled.next-btn-normal:link,.next-btn.disabled.next-btn-normal:visited,.next-btn[disabled].next-btn-normal,.next-btn[disabled].next-btn-normal.visited,.next-btn[disabled].next-btn-normal:link,.next-btn[disabled].next-btn-normal:visited{color:#ccc}.next-btn.disabled.next-btn-normal.active,.next-btn.disabled.next-btn-normal.hover,.next-btn.disabled.next-btn-normal:active,.next-btn.disabled.next-btn-normal:focus,.next-btn.disabled.next-btn-normal:hover,.next-btn[disabled].next-btn-normal.active,.next-btn[disabled].next-btn-normal.hover,.next-btn[disabled].next-btn-normal:active,.next-btn[disabled].next-btn-normal:focus,.next-btn[disabled].next-btn-normal:hover{color:#ccc;background:#fafafa;border-color:#eee;text-decoration:none}.next-btn.disabled.next-btn-primary,.next-btn[disabled].next-btn-primary{background:#fafafa;border-color:#eee}.next-btn.disabled.next-btn-primary,.next-btn.disabled.next-btn-primary.visited,.next-btn.disabled.next-btn-primary:link,.next-btn.disabled.next-btn-primary:visited,.next-btn[disabled].next-btn-primary,.next-btn[disabled].next-btn-primary.visited,.next-btn[disabled].next-btn-primary:link,.next-btn[disabled].next-btn-primary:visited{color:#ccc}.next-btn.disabled.next-btn-primary.active,.next-btn.disabled.next-btn-primary.hover,.next-btn.disabled.next-btn-primary:active,.next-btn.disabled.next-btn-primary:focus,.next-btn.disabled.next-btn-primary:hover,.next-btn[disabled].next-btn-primary.active,.next-btn[disabled].next-btn-primary.hover,.next-btn[disabled].next-btn-primary:active,.next-btn[disabled].next-btn-primary:focus,.next-btn[disabled].next-btn-primary:hover{color:#ccc;background:#fafafa;border-color:#eee;text-decoration:none}.next-btn.disabled.next-btn-secondary,.next-btn[disabled].next-btn-secondary{background:#fafafa;border-color:#eee}.next-btn.disabled.next-btn-secondary,.next-btn.disabled.next-btn-secondary.visited,.next-btn.disabled.next-btn-secondary:link,.next-btn.disabled.next-btn-secondary:visited,.next-btn[disabled].next-btn-secondary,.next-btn[disabled].next-btn-secondary.visited,.next-btn[disabled].next-btn-secondary:link,.next-btn[disabled].next-btn-secondary:visited{color:#ccc}.next-btn.disabled.next-btn-secondary.active,.next-btn.disabled.next-btn-secondary.hover,.next-btn.disabled.next-btn-secondary:active,.next-btn.disabled.next-btn-secondary:focus,.next-btn.disabled.next-btn-secondary:hover,.next-btn[disabled].next-btn-secondary.active,.next-btn[disabled].next-btn-secondary.hover,.next-btn[disabled].next-btn-secondary:active,.next-btn[disabled].next-btn-secondary:focus,.next-btn[disabled].next-btn-secondary:hover{color:#ccc;background:#fafafa;border-color:#eee;text-decoration:none}.next-btn-warning{border-style:solid}.next-btn-warning.next-btn-primary{background:#d23c26;border-color:#d23c26}.next-btn-warning.next-btn-primary,.next-btn-warning.next-btn-primary.visited,.next-btn-warning.next-btn-primary:link,.next-btn-warning.next-btn-primary:visited{color:#fff}.next-btn-warning.next-btn-primary.active,.next-btn-warning.next-btn-primary.hover,.next-btn-warning.next-btn-primary:active,.next-btn-warning.next-btn-primary:focus,.next-btn-warning.next-btn-primary:hover{color:#fff;background:#b7321e;border-color:#b7321e;text-decoration:none}.next-btn-warning.next-btn-primary.disabled,.next-btn-warning.next-btn-primary[disabled]{background:#fafafa;border-color:#e6e6e6}.next-btn-warning.next-btn-primary.disabled,.next-btn-warning.next-btn-primary.disabled.visited,.next-btn-warning.next-btn-primary.disabled:link,.next-btn-warning.next-btn-primary.disabled:visited,.next-btn-warning.next-btn-primary[disabled],.next-btn-warning.next-btn-primary[disabled].visited,.next-btn-warning.next-btn-primary[disabled]:link,.next-btn-warning.next-btn-primary[disabled]:visited{color:#ccc}.next-btn-warning.next-btn-primary.disabled.active,.next-btn-warning.next-btn-primary.disabled.hover,.next-btn-warning.next-btn-primary.disabled:active,.next-btn-warning.next-btn-primary.disabled:focus,.next-btn-warning.next-btn-primary.disabled:hover,.next-btn-warning.next-btn-primary[disabled].active,.next-btn-warning.next-btn-primary[disabled].hover,.next-btn-warning.next-btn-primary[disabled]:active,.next-btn-warning.next-btn-primary[disabled]:focus,.next-btn-warning.next-btn-primary[disabled]:hover{color:#ccc;background:#fafafa;border-color:#e6e6e6;text-decoration:none}.next-btn-warning.next-btn-normal{background:#fff;border-color:#d23c26}.next-btn-warning.next-btn-normal,.next-btn-warning.next-btn-normal.visited,.next-btn-warning.next-btn-normal:link,.next-btn-warning.next-btn-normal:visited{color:#d23c26}.next-btn-warning.next-btn-normal.active,.next-btn-warning.next-btn-normal.hover,.next-btn-warning.next-btn-normal:active,.next-btn-warning.next-btn-normal:focus,.next-btn-warning.next-btn-normal:hover{color:#fff;background:#b7321e;border-color:#b7321e;text-decoration:none}.next-btn-warning.next-btn-normal.disabled,.next-btn-warning.next-btn-normal[disabled]{background:#fafafa;border-color:#eee}.next-btn-warning.next-btn-normal.disabled,.next-btn-warning.next-btn-normal.disabled.visited,.next-btn-warning.next-btn-normal.disabled:link,.next-btn-warning.next-btn-normal.disabled:visited,.next-btn-warning.next-btn-normal[disabled],.next-btn-warning.next-btn-normal[disabled].visited,.next-btn-warning.next-btn-normal[disabled]:link,.next-btn-warning.next-btn-normal[disabled]:visited{color:#ccc}.next-btn-warning.next-btn-normal.disabled.active,.next-btn-warning.next-btn-normal.disabled.hover,.next-btn-warning.next-btn-normal.disabled:active,.next-btn-warning.next-btn-normal.disabled:focus,.next-btn-warning.next-btn-normal.disabled:hover,.next-btn-warning.next-btn-normal[disabled].active,.next-btn-warning.next-btn-normal[disabled].hover,.next-btn-warning.next-btn-normal[disabled]:active,.next-btn-warning.next-btn-normal[disabled]:focus,.next-btn-warning.next-btn-normal[disabled]:hover{color:#ccc;background:#fafafa;border-color:#eee;text-decoration:none}.next-btn-text{border-radius:0;user-select:text}.next-btn-text,.next-btn-text.hover,.next-btn-text:hover{box-shadow:none}.next-btn-text.next-btn-primary{background:transparent;border-color:transparent}.next-btn-text.next-btn-primary,.next-btn-text.next-btn-primary.visited,.next-btn-text.next-btn-primary:link,.next-btn-text.next-btn-primary:visited{color:#298dff}.next-btn-text.next-btn-primary.active,.next-btn-text.next-btn-primary.hover,.next-btn-text.next-btn-primary:active,.next-btn-text.next-btn-primary:focus,.next-btn-text.next-btn-primary:hover{color:#1274e7;background:transparent;border-color:transparent;text-decoration:none}.next-btn-text.next-btn-primary.disabled,.next-btn-text.next-btn-primary[disabled]{background:transparent;border-color:transparent}.next-btn-text.next-btn-primary.disabled,.next-btn-text.next-btn-primary.disabled.visited,.next-btn-text.next-btn-primary.disabled:link,.next-btn-text.next-btn-primary.disabled:visited,.next-btn-text.next-btn-primary[disabled],.next-btn-text.next-btn-primary[disabled].visited,.next-btn-text.next-btn-primary[disabled]:link,.next-btn-text.next-btn-primary[disabled]:visited{color:#ccc}.next-btn-text.next-btn-primary.disabled.active,.next-btn-text.next-btn-primary.disabled.hover,.next-btn-text.next-btn-primary.disabled:active,.next-btn-text.next-btn-primary.disabled:focus,.next-btn-text.next-btn-primary.disabled:hover,.next-btn-text.next-btn-primary[disabled].active,.next-btn-text.next-btn-primary[disabled].hover,.next-btn-text.next-btn-primary[disabled]:active,.next-btn-text.next-btn-primary[disabled]:focus,.next-btn-text.next-btn-primary[disabled]:hover{color:#ccc;background:transparent;border-color:transparent;text-decoration:none}.next-btn-text.next-btn-secondary{background:transparent;border-color:transparent}.next-btn-text.next-btn-secondary,.next-btn-text.next-btn-secondary.visited,.next-btn-text.next-btn-secondary:link,.next-btn-text.next-btn-secondary:visited{color:#666}.next-btn-text.next-btn-secondary.active,.next-btn-text.next-btn-secondary.hover,.next-btn-text.next-btn-secondary:active,.next-btn-text.next-btn-secondary:focus,.next-btn-text.next-btn-secondary:hover{color:#209bfa;background:transparent;border-color:transparent;text-decoration:none}.next-btn-text.next-btn-secondary.disabled,.next-btn-text.next-btn-secondary[disabled]{background:transparent;border-color:transparent}.next-btn-text.next-btn-secondary.disabled,.next-btn-text.next-btn-secondary.disabled.visited,.next-btn-text.next-btn-secondary.disabled:link,.next-btn-text.next-btn-secondary.disabled:visited,.next-btn-text.next-btn-secondary[disabled],.next-btn-text.next-btn-secondary[disabled].visited,.next-btn-text.next-btn-secondary[disabled]:link,.next-btn-text.next-btn-secondary[disabled]:visited{color:#ccc}.next-btn-text.next-btn-secondary.disabled.active,.next-btn-text.next-btn-secondary.disabled.hover,.next-btn-text.next-btn-secondary.disabled:active,.next-btn-text.next-btn-secondary.disabled:focus,.next-btn-text.next-btn-secondary.disabled:hover,.next-btn-text.next-btn-secondary[disabled].active,.next-btn-text.next-btn-secondary[disabled].hover,.next-btn-text.next-btn-secondary[disabled]:active,.next-btn-text.next-btn-secondary[disabled]:focus,.next-btn-text.next-btn-secondary[disabled]:hover{color:#ccc;background:transparent;border-color:transparent;text-decoration:none}.next-btn-text.next-btn-normal{background:transparent;border-color:transparent}.next-btn-text.next-btn-normal,.next-btn-text.next-btn-normal.visited,.next-btn-text.next-btn-normal:link,.next-btn-text.next-btn-normal:visited{color:#333}.next-btn-text.next-btn-normal.active,.next-btn-text.next-btn-normal.hover,.next-btn-text.next-btn-normal:active,.next-btn-text.next-btn-normal:focus,.next-btn-text.next-btn-normal:hover{color:#209bfa;background:transparent;border-color:transparent;text-decoration:none}.next-btn-text.next-btn-normal.disabled,.next-btn-text.next-btn-normal[disabled]{background:transparent;border-color:transparent}.next-btn-text.next-btn-normal.disabled,.next-btn-text.next-btn-normal.disabled.visited,.next-btn-text.next-btn-normal.disabled:link,.next-btn-text.next-btn-normal.disabled:visited,.next-btn-text.next-btn-normal[disabled],.next-btn-text.next-btn-normal[disabled].visited,.next-btn-text.next-btn-normal[disabled]:link,.next-btn-text.next-btn-normal[disabled]:visited{color:#ccc}.next-btn-text.next-btn-normal.disabled.active,.next-btn-text.next-btn-normal.disabled.hover,.next-btn-text.next-btn-normal.disabled:active,.next-btn-text.next-btn-normal.disabled:focus,.next-btn-text.next-btn-normal.disabled:hover,.next-btn-text.next-btn-normal[disabled].active,.next-btn-text.next-btn-normal[disabled].hover,.next-btn-text.next-btn-normal[disabled]:active,.next-btn-text.next-btn-normal[disabled]:focus,.next-btn-text.next-btn-normal[disabled]:hover{color:#ccc;background:transparent;border-color:transparent;text-decoration:none}.next-btn-text.next-large{border-radius:0;padding:0;height:24px;font-size:14px;border-width:0}.next-btn-text.next-large>.next-btn-icon.next-icon-first{transform:scale(1);margin-left:0;margin-right:4px}.next-btn-text.next-large>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text.next-large>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text.next-large>.next-btn-icon.next-icon-last{transform:scale(1);margin-left:4px;margin-right:0}.next-btn-text.next-large>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text.next-large>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text.next-large>.next-btn-icon.next-icon-alone{transform:scale(1)}.next-btn-text.next-large>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn-text.next-large>.next-btn-icon.next-icon-alone:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text.next-large>.next-btn-icon-size{margin-right:4px}.next-btn-text.next-large.next-btn-loading:before{width:20px;height:20px;font-size:20px;line-height:20px;left:0;top:50%;text-align:center;margin-right:4px}.next-btn-text.next-large.next-btn-loading>.next-icon{display:none}.next-btn-text.next-large>.next-btn-custom-loading-icon{opacity:0;width:0}.next-btn-text.next-large>.next-btn-custom-loading-icon.show{width:20px;margin-right:4px;opacity:1;transition:all .1s linear}.next-btn-text.next-medium{border-radius:0;padding:0;height:20px;font-size:14px;border-width:0}.next-btn-text.next-medium>.next-btn-icon.next-icon-first{transform:scale(1);margin-left:0;margin-right:4px}.next-btn-text.next-medium>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text.next-medium>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text.next-medium>.next-btn-icon.next-icon-last{transform:scale(1);margin-left:4px;margin-right:0}.next-btn-text.next-medium>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text.next-medium>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text.next-medium>.next-btn-icon.next-icon-alone{transform:scale(1)}.next-btn-text.next-medium>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn-text.next-medium>.next-btn-icon.next-icon-alone:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text.next-medium>.next-btn-icon-size{margin-right:4px}.next-btn-text.next-medium.next-btn-loading:before{width:20px;height:20px;font-size:20px;line-height:20px;left:0;top:50%;text-align:center;margin-right:4px}.next-btn-text.next-medium.next-btn-loading>.next-icon{display:none}.next-btn-text.next-medium>.next-btn-custom-loading-icon{opacity:0;width:0}.next-btn-text.next-medium>.next-btn-custom-loading-icon.show{width:20px;margin-right:4px;opacity:1;transition:all .1s linear}.next-btn-text.next-small{border-radius:0;padding:0;height:16px;font-size:12px;border-width:0}.next-btn-text.next-small>.next-btn-icon.next-icon-first{transform:scale(1);margin-left:0;margin-right:4px}.next-btn-text.next-small>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text.next-small>.next-btn-icon.next-icon-first:before{width:12px;font-size:12px;line-height:inherit}.next-btn-text.next-small>.next-btn-icon.next-icon-last{transform:scale(1);margin-left:4px;margin-right:0}.next-btn-text.next-small>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text.next-small>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px;line-height:inherit}.next-btn-text.next-small>.next-btn-icon.next-icon-alone{transform:scale(1)}.next-btn-text.next-small>.next-btn-icon.next-icon-alone .next-icon-remote,.next-btn-text.next-small>.next-btn-icon.next-icon-alone:before{width:12px;font-size:12px;line-height:inherit}.next-btn-text.next-small>.next-btn-icon-size{margin-right:4px}.next-btn-text.next-small.next-btn-loading:before{width:12px;height:12px;font-size:12px;line-height:12px;left:0;top:50%;text-align:center;margin-right:4px}.next-btn-text.next-small.next-btn-loading>.next-icon{display:none}.next-btn-text.next-small>.next-btn-custom-loading-icon{opacity:0;width:0}.next-btn-text.next-small>.next-btn-custom-loading-icon.show{width:12px;margin-right:4px;opacity:1;transition:all .1s linear}.next-btn-text.next-btn-loading{background:transparent;border-color:transparent}.next-btn-text.next-btn-loading,.next-btn-text.next-btn-loading.visited,.next-btn-text.next-btn-loading:link,.next-btn-text.next-btn-loading:visited{color:#333}.next-btn-text.next-btn-loading.active,.next-btn-text.next-btn-loading.hover,.next-btn-text.next-btn-loading:active,.next-btn-text.next-btn-loading:focus,.next-btn-text.next-btn-loading:hover{color:#333;background:transparent;border-color:transparent;text-decoration:none}.next-btn-loading{pointer-events:none}.next-btn-loading:before{font-family:NextIcon;content:"";opacity:1;visibility:visible;animation:loadingCircle 2s linear infinite}.next-btn-loading:after{content:"";display:inline-block;position:static;height:100%;width:0;vertical-align:middle}.next-btn-custom-loading{pointer-events:none}.next-btn-ghost{box-shadow:none;border-style:solid}.next-btn-ghost.next-btn-dark{background:transparent;border-color:#fff}.next-btn-ghost.next-btn-dark,.next-btn-ghost.next-btn-dark.visited,.next-btn-ghost.next-btn-dark:link,.next-btn-ghost.next-btn-dark:visited{color:#fff}.next-btn-ghost.next-btn-dark.active,.next-btn-ghost.next-btn-dark.hover,.next-btn-ghost.next-btn-dark:active,.next-btn-ghost.next-btn-dark:focus,.next-btn-ghost.next-btn-dark:hover{color:#fff;background:hsla(0,0%,100%,.8);border-color:#fff;text-decoration:none}.next-btn-ghost.next-btn-dark.disabled,.next-btn-ghost.next-btn-dark[disabled]{background:transparent;border-color:hsla(0,0%,100%,.4)}.next-btn-ghost.next-btn-dark.disabled,.next-btn-ghost.next-btn-dark.disabled.visited,.next-btn-ghost.next-btn-dark.disabled:link,.next-btn-ghost.next-btn-dark.disabled:visited,.next-btn-ghost.next-btn-dark[disabled],.next-btn-ghost.next-btn-dark[disabled].visited,.next-btn-ghost.next-btn-dark[disabled]:link,.next-btn-ghost.next-btn-dark[disabled]:visited{color:hsla(0,0%,100%,.4)}.next-btn-ghost.next-btn-dark.disabled.active,.next-btn-ghost.next-btn-dark.disabled.hover,.next-btn-ghost.next-btn-dark.disabled:active,.next-btn-ghost.next-btn-dark.disabled:focus,.next-btn-ghost.next-btn-dark.disabled:hover,.next-btn-ghost.next-btn-dark[disabled].active,.next-btn-ghost.next-btn-dark[disabled].hover,.next-btn-ghost.next-btn-dark[disabled]:active,.next-btn-ghost.next-btn-dark[disabled]:focus,.next-btn-ghost.next-btn-dark[disabled]:hover{color:hsla(0,0%,100%,.4);background:transparent;border-color:hsla(0,0%,100%,.4);text-decoration:none}.next-btn-ghost.next-btn-light{background:transparent;border-color:#333}.next-btn-ghost.next-btn-light,.next-btn-ghost.next-btn-light.visited,.next-btn-ghost.next-btn-light:link,.next-btn-ghost.next-btn-light:visited{color:#333}.next-btn-ghost.next-btn-light.active,.next-btn-ghost.next-btn-light.hover,.next-btn-ghost.next-btn-light:active,.next-btn-ghost.next-btn-light:focus,.next-btn-ghost.next-btn-light:hover{color:#999;background:rgba(0,0,0,.92);border-color:#333;text-decoration:none}.next-btn-ghost.next-btn-light.disabled,.next-btn-ghost.next-btn-light[disabled]{background:transparent;border-color:rgba(0,0,0,.1)}.next-btn-ghost.next-btn-light.disabled,.next-btn-ghost.next-btn-light.disabled.visited,.next-btn-ghost.next-btn-light.disabled:link,.next-btn-ghost.next-btn-light.disabled:visited,.next-btn-ghost.next-btn-light[disabled],.next-btn-ghost.next-btn-light[disabled].visited,.next-btn-ghost.next-btn-light[disabled]:link,.next-btn-ghost.next-btn-light[disabled]:visited{color:rgba(0,0,0,.1)}.next-btn-ghost.next-btn-light.disabled.active,.next-btn-ghost.next-btn-light.disabled.hover,.next-btn-ghost.next-btn-light.disabled:active,.next-btn-ghost.next-btn-light.disabled:focus,.next-btn-ghost.next-btn-light.disabled:hover,.next-btn-ghost.next-btn-light[disabled].active,.next-btn-ghost.next-btn-light[disabled].hover,.next-btn-ghost.next-btn-light[disabled]:active,.next-btn-ghost.next-btn-light[disabled]:focus,.next-btn-ghost.next-btn-light[disabled]:hover{color:rgba(0,0,0,.1);background:transparent;border-color:rgba(0,0,0,.1);text-decoration:none}.next-btn-group{position:relative;display:inline-block;vertical-align:middle}.next-btn-group>.next-btn{position:relative;float:left;box-shadow:none}.next-btn-group>.next-btn.active,.next-btn-group>.next-btn:active,.next-btn-group>.next-btn:focus,.next-btn-group>.next-btn:hover{z-index:1}.next-btn-group>.next-btn.disabled,.next-btn-group>.next-btn[disabled]{z-index:0}.next-btn-group .next-btn.next-btn{margin:0 0 0 -1px}.next-btn-group .next-btn:not(:first-child):not(:last-child){border-radius:0}.next-btn-group>.next-btn:first-child{margin:0}.next-btn-group>.next-btn:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.next-btn-group>.next-btn:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.next-btn-group>.next-btn-primary:not(:first-child){border-left-color:hsla(0,0%,100%,.2)}.next-btn-group>.next-btn-primary:not(:first-child):hover{border-left-color:transparent}.next-btn-group>.next-btn-primary:not(:first-child).disabled,.next-btn-group>.next-btn-primary:not(:first-child)[disabled]{border-left-color:#eee}.next-btn-group[dir=rtl]>.next-btn{float:right}.next-btn-group[dir=rtl] .next-btn.next-btn{margin:0 -1px 0 0}.next-btn-group[dir=rtl]>.next-btn:first-child:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.next-btn-group[dir=rtl]>.next-btn:last-child:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0}.next-btn-group[dir=rtl]>.next-btn-primary:not(:first-child){border-right-color:hsla(0,0%,100%,.2)}.next-btn-group[dir=rtl]>.next-btn-primary:not(:first-child):hover{border-right-color:transparent}.next-btn-group[dir=rtl]>.next-btn-primary:not(:first-child).disabled,.next-btn-group[dir=rtl]>.next-btn-primary:not(:first-child)[disabled]{border-right-color:#eee}.next-btn.next-small[dir=rtl]{border-radius:3px}.next-btn.next-small[dir=rtl]>.next-btn-icon.next-icon-first{margin-left:4px;margin-right:0}.next-btn.next-small[dir=rtl]>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-small[dir=rtl]>.next-btn-icon.next-icon-first:before{width:12px;font-size:12px;line-height:inherit}.next-btn.next-small[dir=rtl]>.next-btn-icon.next-icon-last{margin-left:0;margin-right:4px}.next-btn.next-small[dir=rtl]>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-small[dir=rtl]>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px;line-height:inherit}.next-btn.next-small[dir=rtl].next-btn-loading{padding-left:16px;padding-right:32px}.next-btn.next-small[dir=rtl].next-btn-loading:after{right:16px;top:50%;margin-right:0;margin-left:4px}.next-btn.next-medium[dir=rtl]{border-radius:3px}.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-first{margin-left:4px;margin-right:0}.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-last{margin-left:0;margin-right:4px}.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-medium[dir=rtl]>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-medium[dir=rtl].next-btn-loading{padding-left:20px;padding-right:44px}.next-btn.next-medium[dir=rtl].next-btn-loading:after{right:20px;top:50%;margin-right:0;margin-left:4px}.next-btn.next-large[dir=rtl]{border-radius:3px}.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-first{margin-left:4px;margin-right:0}.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-last{margin-left:0;margin-right:4px}.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn.next-large[dir=rtl]>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn.next-large[dir=rtl].next-btn-loading{padding-left:24px;padding-right:48px}.next-btn.next-large[dir=rtl].next-btn-loading:after{right:24px;top:50%;margin-right:0;margin-left:4px}.next-btn-text[dir=rtl].next-large{border-radius:0}.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-first{margin-left:4px;margin-right:0}.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-last{margin-left:0;margin-right:4px}.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text[dir=rtl].next-large>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text[dir=rtl].next-large.next-btn-loading{padding-left:0;padding-right:24px}.next-btn-text[dir=rtl].next-large.next-btn-loading:after{right:0;top:50%;margin-right:0;margin-left:4px}.next-btn-text[dir=rtl].next-medium{border-radius:0}.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-first{margin-left:4px;margin-right:0}.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-first:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-last{margin-left:0;margin-right:4px}.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text[dir=rtl].next-medium>.next-btn-icon.next-icon-last:before{width:20px;font-size:20px;line-height:inherit}.next-btn-text[dir=rtl].next-medium.next-btn-loading{padding-left:0;padding-right:24px}.next-btn-text[dir=rtl].next-medium.next-btn-loading:after{right:0;top:50%;margin-right:0;margin-left:4px}.next-btn-text[dir=rtl].next-small{border-radius:0}.next-btn-text[dir=rtl].next-small>.next-btn-icon.next-icon-first{margin-left:4px;margin-right:0}.next-btn-text[dir=rtl].next-small>.next-btn-icon.next-icon-first .next-icon-remote,.next-btn-text[dir=rtl].next-small>.next-btn-icon.next-icon-first:before{width:12px;font-size:12px;line-height:inherit}.next-btn-text[dir=rtl].next-small>.next-btn-icon.next-icon-last{margin-left:0;margin-right:4px}.next-btn-text[dir=rtl].next-small>.next-btn-icon.next-icon-last .next-icon-remote,.next-btn-text[dir=rtl].next-small>.next-btn-icon.next-icon-last:before{width:12px;font-size:12px;line-height:inherit}.next-btn-text[dir=rtl].next-small.next-btn-loading{padding-left:0;padding-right:16px}.next-btn-text[dir=rtl].next-small.next-btn-loading:after{right:0;top:50%;margin-right:0;margin-left:4px}.next-input{vertical-align:middle;display:inline-table;border-collapse:separate;font-size:0;line-height:1;width:200px;border-spacing:0;transition:all .1s linear;border:1px solid #ddd;background-color:#fff}.next-input,.next-input *,.next-input :after,.next-input :before{box-sizing:border-box}.next-input input{height:100%}.next-input input[type=reset],.next-input input[type=submit]{-webkit-appearance:button;cursor:pointer}.next-input input::-moz-focus-inner{border:0;padding:0}.next-input input:-webkit-autofill{-webkit-box-shadow:0 0 0 1000px #fff inset;border-radius:3px}.next-input input[type=password]::-ms-reveal{display:none}.next-input textarea{resize:none}.next-input input,.next-input textarea{width:100%;border:none;outline:none;padding:0;margin:0;font-weight:400;vertical-align:middle;background-color:transparent;color:#333}.next-input input::-ms-clear,.next-input textarea::-ms-clear{display:none}.next-input.next-small{height:24px;border-radius:3px}.next-input.next-small .next-input-label{padding-left:8px;font-size:12px}.next-input.next-small .next-input-inner{font-size:12px}.next-input.next-small .next-input-control,.next-input.next-small .next-input-inner-text{padding-right:4px}.next-input.next-small input{height:22px;line-height:22px \0 ;padding:0 4px;font-size:12px}.next-input.next-small input::placeholder{font-size:12px}.next-input.next-small .next-input-text-field{padding:0 4px;font-size:12px;height:22px;line-height:22px}.next-input.next-small .next-icon .next-icon-remote,.next-input.next-small .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-input.next-small .next-input-control{border-radius:0 3px 3px 0}.next-input.next-medium{height:32px;border-radius:3px}.next-input.next-medium .next-input-label{padding-left:8px;font-size:14px}.next-input.next-medium .next-input-inner{font-size:14px}.next-input.next-medium .next-input-control,.next-input.next-medium .next-input-inner-text{padding-right:8px}.next-input.next-medium input{height:30px;line-height:30px \0 ;padding:0 8px;font-size:14px}.next-input.next-medium input::placeholder{font-size:14px}.next-input.next-medium .next-input-text-field{padding:0 8px;font-size:14px;height:30px;line-height:30px}.next-input.next-medium .next-icon .next-icon-remote,.next-input.next-medium .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-input.next-medium .next-input-control{border-radius:0 3px 3px 0}.next-input.next-large{height:40px;border-radius:3px}.next-input.next-large .next-input-label{padding-left:12px;font-size:16px}.next-input.next-large .next-input-inner{font-size:16px}.next-input.next-large .next-input-control,.next-input.next-large .next-input-inner-text{padding-right:8px}.next-input.next-large input{height:38px;line-height:38px \0 ;padding:0 12px;font-size:16px}.next-input.next-large input::placeholder{font-size:16px}.next-input.next-large .next-input-text-field{padding:0 12px;font-size:16px;height:38px;line-height:38px}.next-input.next-large .next-icon .next-icon-remote,.next-input.next-large .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-input.next-large .next-input-control{border-radius:0 3px 3px 0}.next-input.next-input-textarea{height:auto;border-radius:3px;font-size:0}.next-input.next-input-textarea textarea{color:#333;padding:4px 8px;font-size:14px;border-radius:3px}.next-input.next-input-textarea.next-small textarea{font-size:14px}.next-input.next-input-textarea.next-large textarea{font-size:16px}.next-input.next-input-textarea .next-input-control{display:block;width:auto;border-radius:3px}.next-input.next-input-textarea .next-input-len{padding:0 8px 4px;display:block;text-align:right;width:auto}.next-input-hint-wrap{color:#999;position:relative}.next-input-hint-wrap .next-input-clear{opacity:0;z-index:1;position:absolute}.next-input-hint-wrap .next-input-hint{opacity:1}.next-input .next-icon-eye-close:hover,.next-input .next-icon-eye:hover,.next-input .next-input-clear-icon:hover{cursor:pointer;color:#666}.next-input .next-input-hover-show{opacity:0}.next-input.next-focus,.next-input:hover{border-color:#ccc;background-color:#fff}.next-input.next-focus .next-input-clear,.next-input:hover .next-input-clear{opacity:1}.next-input.next-focus .next-input-clear+.next-input-hint,.next-input:hover .next-input-clear+.next-input-hint{opacity:0}.next-input.next-focus .next-input-hover-show,.next-input .next-input-clear:focus,.next-input:hover .next-input-hover-show{opacity:1}.next-input .next-input-clear:focus+.next-input-hint{opacity:0}.next-input.next-focus{border-color:#209bfa;background-color:#fff;box-shadow:0 0 0 2px rgba(32,155,250,.2)}.next-input.next-warning{border-color:#f1c826;background-color:#fff}.next-input.next-warning.next-focus,.next-input.next-warning:hover{border-color:#f1c826}.next-input.next-warning.next-focus{box-shadow:0 0 0 2px rgba(241,200,38,.2)}.next-input.next-error{border-color:#d23c26;background-color:#fff}.next-input.next-error input,.next-input.next-error textarea{color:#333}.next-input.next-error.next-focus,.next-input.next-error:hover{border-color:#d23c26}.next-input.next-error.next-focus{box-shadow:0 0 0 2px rgba(210,60,38,.2)}.next-input.next-hidden{display:none}.next-input.next-noborder{border:none;box-shadow:none}.next-input-control .next-input-len{font-size:12px;line-height:12px;color:#999;display:table-cell;width:1px;vertical-align:bottom}.next-input-control .next-input-len.next-error{color:#d23c26}.next-input-control .next-input-len.next-warning{color:#f1c826}.next-input-control>*{display:table-cell;width:1%;top:0}.next-input-control>:not(:last-child){padding-right:4px}.next-input-control .next-icon{transition:all .1s linear;color:#999}.next-input-control .next-input-warning-icon{color:#f1c826}.next-input-control .next-input-warning-icon:before{content:""}.next-input-control .next-input-success-icon{color:#1ad78c}.next-input-control .next-input-success-icon:before{content:""}.next-input-control .next-input-loading-icon{color:#298dff}.next-input-control .next-input-loading-icon:before{content:"";animation:loadingCircle 1s linear infinite}.next-input-control .next-input-clear-icon:before{content:""}.next-input-inner-text,.next-input-label{color:#666}.next-input input::-moz-placeholder,.next-input textarea::-moz-placeholder{color:#ccc;opacity:1}.next-input input:-ms-input-placeholder,.next-input textarea:-ms-input-placeholder{color:#ccc}.next-input input::-webkit-input-placeholder,.next-input textarea::-webkit-input-placeholder{color:#ccc}.next-input.next-disabled{color:#ccc;cursor:not-allowed}.next-input.next-disabled,.next-input.next-disabled:hover{border-color:#eee;background-color:#fafafa}.next-input.next-disabled input,.next-input.next-disabled textarea{-webkit-text-fill-color:#ccc;color:#ccc}.next-input.next-disabled input::-moz-placeholder,.next-input.next-disabled textarea::-moz-placeholder{color:#ccc;opacity:1}.next-input.next-disabled input:-ms-input-placeholder,.next-input.next-disabled textarea:-ms-input-placeholder{color:#ccc}.next-input.next-disabled input::-webkit-input-placeholder,.next-input.next-disabled textarea::-webkit-input-placeholder{color:#ccc}.next-input.next-disabled .next-input-hint-wrap,.next-input.next-disabled .next-input-inner-text,.next-input.next-disabled .next-input-label,.next-input.next-disabled .next-input-len{color:#ccc}.next-input.next-disabled .next-input-hint-wrap .next-input-clear{opacity:0}.next-input.next-disabled .next-input-hint-wrap .next-input-hint{opacity:1}.next-input.next-disabled .next-input-hint-wrap .next-input-clear-icon:hover{cursor:not-allowed;color:#ccc}.next-input.next-disabled .next-icon{color:#ccc}.next-input-control,.next-input-inner,.next-input-label{display:table-cell;width:1px;vertical-align:middle;line-height:1;background-color:transparent;white-space:nowrap}.next-input-group{display:inline-table;border-collapse:separate;border-spacing:0;line-height:0;width:100%;overflow:hidden}.next-input-group,.next-input-group *,.next-input-group :after,.next-input-group :before{box-sizing:border-box}.next-input-group-auto-width{width:100%;border-radius:0!important}.next-input-group>.next-input{border-radius:0}.next-input-group>.next-input.next-focus,.next-input-group>.next-input:hover{position:relative;z-index:1}.next-input-group>.next-input:first-child.next-large,.next-input-group>.next-input:first-child.next-medium,.next-input-group>.next-input:first-child.next-small{border-top-left-radius:3px!important;border-bottom-left-radius:3px!important}.next-input-group>.next-input:last-child.next-large,.next-input-group>.next-input:last-child.next-medium,.next-input-group>.next-input:last-child.next-small{border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.next-input-group-addon{width:1px;display:table-cell;vertical-align:middle;white-space:nowrap}.next-input-group-addon:first-child,.next-input-group-addon:first-child>*{border-bottom-right-radius:0!important;border-top-right-radius:0!important}.next-input-group-addon:first-child>*{margin-right:-1px}.next-input-group-addon:first-child>.next-focus{position:relative;z-index:1}.next-input-group-addon:first-child>*>.next-input{border-bottom-right-radius:0!important;border-top-right-radius:0!important}.next-input-group-addon:first-child>*>.next-input.next-focus{position:relative;z-index:1}.next-input-group-addon:last-child,.next-input-group-addon:last-child>*{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.next-input-group-addon:last-child>*{margin-left:-1px}.next-input-group-addon:last-child>*>.next-input{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.next-input-group-text{color:#999;background-color:#f9f9f9;text-align:center;border:1px solid #ddd;padding:0 8px}.next-input-group-text:first-child{border-right-width:0}.next-input-group-text:last-child{border-left-width:0}.next-input-group-text.next-disabled{color:#ccc;cursor:not-allowed}.next-input-group-text.next-disabled,.next-input-group-text.next-disabled:hover{border-color:#eee;background-color:#fafafa}.next-input-group-text.next-small{font-size:12px;border-radius:3px}.next-input-group-text.next-medium{font-size:14px;border-radius:3px}.next-input-group-text.next-large{font-size:16px;border-radius:3px}.next-input[dir=rtl].next-small .next-input-label{padding-left:0;padding-right:8px}.next-input[dir=rtl].next-small .next-input-control{padding-right:0;padding-left:4px}.next-input[dir=rtl].next-medium .next-input-label{padding-left:0;padding-right:8px}.next-input[dir=rtl].next-medium .next-input-control{padding-right:0;padding-left:8px}.next-input[dir=rtl].next-large .next-input-label{padding-left:0;padding-right:12px}.next-input[dir=rtl].next-large .next-input-control{padding-right:0;padding-left:8px}.next-input[dir=rtl].next-input-textarea .next-input-len{text-align:left}.next-input[dir=rtl] .next-input-control>:not(:last-child){padding-left:4px;padding-right:0}.next-input-group[dir=rtl]>.next-input:first-child.next-large,.next-input-group[dir=rtl]>.next-input:first-child.next-medium,.next-input-group[dir=rtl]>.next-input:first-child.next-small{border-top-left-radius:0!important;border-bottom-left-radius:0!important;border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.next-input-group[dir=rtl]>.next-input:last-child.next-large,.next-input-group[dir=rtl]>.next-input:last-child.next-medium,.next-input-group[dir=rtl]>.next-input:last-child.next-small{border-top-left-radius:3px!important;border-bottom-left-radius:3px!important;border-top-right-radius:0!important;border-bottom-right-radius:0!important}.next-input-group[dir=rtl] .next-input-group-addon:first-child,.next-input-group[dir=rtl] .next-input-group-addon:first-child>*>.next-input,.next-input-group[dir=rtl] .next-input-group-addon:first-child>.next-input{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.next-input-group[dir=rtl] .next-input-group-addon:first-child.next-large,.next-input-group[dir=rtl] .next-input-group-addon:first-child.next-medium,.next-input-group[dir=rtl] .next-input-group-addon:first-child.next-small,.next-input-group[dir=rtl] .next-input-group-addon:first-child>*>.next-input.next-large,.next-input-group[dir=rtl] .next-input-group-addon:first-child>*>.next-input.next-medium,.next-input-group[dir=rtl] .next-input-group-addon:first-child>*>.next-input.next-small,.next-input-group[dir=rtl] .next-input-group-addon:first-child>.next-input.next-large,.next-input-group[dir=rtl] .next-input-group-addon:first-child>.next-input.next-medium,.next-input-group[dir=rtl] .next-input-group-addon:first-child>.next-input.next-small{border-bottom-right-radius:3px!important;border-top-right-radius:3px!important}.next-input-group[dir=rtl] .next-input-group-addon:first-child>*{margin-left:-1px;border-bottom-left-radius:0!important;border-top-left-radius:0!important}.next-input-group[dir=rtl] .next-input-group-addon:last-child,.next-input-group[dir=rtl] .next-input-group-addon:last-child>*>.next-input,.next-input-group[dir=rtl] .next-input-group-addon:last-child>.next-input{border-bottom-right-radius:0!important;border-top-right-radius:0!important}.next-input-group[dir=rtl] .next-input-group-addon:last-child.next-large,.next-input-group[dir=rtl] .next-input-group-addon:last-child.next-medium,.next-input-group[dir=rtl] .next-input-group-addon:last-child.next-small,.next-input-group[dir=rtl] .next-input-group-addon:last-child>*>.next-input.next-large,.next-input-group[dir=rtl] .next-input-group-addon:last-child>*>.next-input.next-medium,.next-input-group[dir=rtl] .next-input-group-addon:last-child>*>.next-input.next-small,.next-input-group[dir=rtl] .next-input-group-addon:last-child>.next-input.next-large,.next-input-group[dir=rtl] .next-input-group-addon:last-child>.next-input.next-medium,.next-input-group[dir=rtl] .next-input-group-addon:last-child>.next-input.next-small{border-bottom-left-radius:3px!important;border-top-left-radius:3px!important}.next-input-group[dir=rtl] .next-input-group-addon:last-child>*{margin-right:-1px;border-bottom-right-radius:0!important;border-top-right-radius:0!important}.next-input-group[dir=rtl] .next-input-group-text:first-child{border-right-width:1px;border-left:0}.next-input-group[dir=rtl] .next-input-group-text:last-child{border-left-width:1px;border-right:0}.next-calendar,.next-calendar *,.next-calendar :after,.next-calendar :before{box-sizing:border-box}.next-calendar table{border-collapse:collapse;border-spacing:0}.next-calendar td,.next-calendar th{padding:0}@keyframes cellZoomIn{0%{transform:scale(.5)}to{transform:scale(1)}}@keyframes cellHover{0%{opacity:0}to{opacity:1}}@keyframes enterToLeft{0%{transform:translate(-40%);opacity:0}50%{opacity:.6}to{opacity:1;transform:translate(0)}}@keyframes enterToRight{0%{transform:translate(40%);opacity:0}50%{opacity:.6}to{opacity:1;transform:translate(0)}}.next-calendar-card .next-calendar-header,.next-calendar-fullscreen .next-calendar-header{text-align:right}.next-calendar-card .next-calendar-header .next-select,.next-calendar-fullscreen .next-calendar-header .next-select{margin-right:4px;vertical-align:top}.next-calendar-card .next-calendar-header .next-menu,.next-calendar-fullscreen .next-calendar-header .next-menu{text-align:left}.next-calendar-card .next-calendar-header,.next-calendar-fullscreen .next-calendar-header{margin-bottom:8px}.next-calendar-panel-header{position:relative;background:#fff;margin-bottom:8px;border-bottom:1px solid transparent}.next-calendar-panel-header-full,.next-calendar-panel-header-left,.next-calendar-panel-header-right{height:32px;line-height:32px}.next-calendar-panel-header-full .next-calendar-btn,.next-calendar-panel-header-left .next-calendar-btn,.next-calendar-panel-header-right .next-calendar-btn{vertical-align:top;font-weight:700;margin:0 4px;background:transparent;border-color:transparent}.next-calendar-panel-header-full .next-calendar-btn,.next-calendar-panel-header-full .next-calendar-btn.visited,.next-calendar-panel-header-full .next-calendar-btn:link,.next-calendar-panel-header-full .next-calendar-btn:visited,.next-calendar-panel-header-left .next-calendar-btn,.next-calendar-panel-header-left .next-calendar-btn.visited,.next-calendar-panel-header-left .next-calendar-btn:link,.next-calendar-panel-header-left .next-calendar-btn:visited,.next-calendar-panel-header-right .next-calendar-btn,.next-calendar-panel-header-right .next-calendar-btn.visited,.next-calendar-panel-header-right .next-calendar-btn:link,.next-calendar-panel-header-right .next-calendar-btn:visited{color:#000}.next-calendar-panel-header-full .next-calendar-btn.active,.next-calendar-panel-header-full .next-calendar-btn.hover,.next-calendar-panel-header-full .next-calendar-btn:active,.next-calendar-panel-header-full .next-calendar-btn:focus,.next-calendar-panel-header-full .next-calendar-btn:hover,.next-calendar-panel-header-left .next-calendar-btn.active,.next-calendar-panel-header-left .next-calendar-btn.hover,.next-calendar-panel-header-left .next-calendar-btn:active,.next-calendar-panel-header-left .next-calendar-btn:focus,.next-calendar-panel-header-left .next-calendar-btn:hover,.next-calendar-panel-header-right .next-calendar-btn.active,.next-calendar-panel-header-right .next-calendar-btn.hover,.next-calendar-panel-header-right .next-calendar-btn:active,.next-calendar-panel-header-right .next-calendar-btn:focus,.next-calendar-panel-header-right .next-calendar-btn:hover{color:#fff;background:transparent;border-color:transparent;text-decoration:none}.next-calendar-panel-header-left,.next-calendar-panel-header-right{display:inline-block;width:50%;text-align:center}.next-calendar-panel-header-full{width:100%;text-align:center}.next-calendar-panel-menu{max-height:210px;overflow:auto;text-align:left}.next-calendar-btn{cursor:pointer;padding:0;margin:0;border:0;background:transparent;outline:none;height:100%}.next-calendar-btn>.next-icon.next-icon .next-icon-remote,.next-calendar-btn>.next-icon.next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-calendar-btn .next-icon{margin-left:4px}.next-calendar-btn-next-decade,.next-calendar-btn-next-month,.next-calendar-btn-next-year,.next-calendar-btn-prev-decade,.next-calendar-btn-prev-month,.next-calendar-btn-prev-year{position:absolute;top:0;background:transparent;border-color:transparent}.next-calendar-btn-next-decade,.next-calendar-btn-next-decade.visited,.next-calendar-btn-next-decade:link,.next-calendar-btn-next-decade:visited,.next-calendar-btn-next-month,.next-calendar-btn-next-month.visited,.next-calendar-btn-next-month:link,.next-calendar-btn-next-month:visited,.next-calendar-btn-next-year,.next-calendar-btn-next-year.visited,.next-calendar-btn-next-year:link,.next-calendar-btn-next-year:visited,.next-calendar-btn-prev-decade,.next-calendar-btn-prev-decade.visited,.next-calendar-btn-prev-decade:link,.next-calendar-btn-prev-decade:visited,.next-calendar-btn-prev-month,.next-calendar-btn-prev-month.visited,.next-calendar-btn-prev-month:link,.next-calendar-btn-prev-month:visited,.next-calendar-btn-prev-year,.next-calendar-btn-prev-year.visited,.next-calendar-btn-prev-year:link,.next-calendar-btn-prev-year:visited{color:#666}.next-calendar-btn-next-decade.active,.next-calendar-btn-next-decade.hover,.next-calendar-btn-next-decade:active,.next-calendar-btn-next-decade:focus,.next-calendar-btn-next-decade:hover,.next-calendar-btn-next-month.active,.next-calendar-btn-next-month.hover,.next-calendar-btn-next-month:active,.next-calendar-btn-next-month:focus,.next-calendar-btn-next-month:hover,.next-calendar-btn-next-year.active,.next-calendar-btn-next-year.hover,.next-calendar-btn-next-year:active,.next-calendar-btn-next-year:focus,.next-calendar-btn-next-year:hover,.next-calendar-btn-prev-decade.active,.next-calendar-btn-prev-decade.hover,.next-calendar-btn-prev-decade:active,.next-calendar-btn-prev-decade:focus,.next-calendar-btn-prev-decade:hover,.next-calendar-btn-prev-month.active,.next-calendar-btn-prev-month.hover,.next-calendar-btn-prev-month:active,.next-calendar-btn-prev-month:focus,.next-calendar-btn-prev-month:hover,.next-calendar-btn-prev-year.active,.next-calendar-btn-prev-year.hover,.next-calendar-btn-prev-year:active,.next-calendar-btn-prev-year:focus,.next-calendar-btn-prev-year:hover{color:#209bfa;background:transparent;border-color:transparent;text-decoration:none}.next-calendar-btn-prev-decade,.next-calendar-btn-prev-year{left:8px}.next-calendar-btn-prev-month{left:28px}.next-calendar-btn-next-month{right:28px}.next-calendar-btn-next-decade,.next-calendar-btn-next-year{right:8px}.next-calendar-fullscreen .next-calendar-th{text-align:right;color:#333;font-size:16px;font-weight:700;padding-right:12px;padding-bottom:4px}.next-calendar-fullscreen .next-calendar-cell{font-size:14px}.next-calendar-fullscreen .next-calendar-cell.next-selected .next-calendar-date,.next-calendar-fullscreen .next-calendar-cell.next-selected .next-calendar-month{font-weight:700;background:#add9ff;color:#209bfa;border-color:#209bfa}.next-calendar-fullscreen .next-calendar-cell.next-disabled .next-calendar-date,.next-calendar-fullscreen .next-calendar-cell.next-disabled .next-calendar-month{cursor:not-allowed;background:#fafafa;color:#ccc;border-color:#eee}.next-calendar-fullscreen .next-calendar-date,.next-calendar-fullscreen .next-calendar-month{text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:0 4px;padding:4px 8px;min-height:80px;transition:background .1s linear;background:#fff;color:#333;border-color:currentcolor #e6e6e6 #e6e6e6;border-top:2px solid #e6e6e6}.next-calendar-fullscreen .next-calendar-date:hover,.next-calendar-fullscreen .next-calendar-month:hover{background:#add9ff;color:#209bfa;border-color:#209bfa}.next-calendar-fullscreen .next-calendar-cell-next-month .next-calendar-date,.next-calendar-fullscreen .next-calendar-cell-prev-month .next-calendar-date{background:transparent;color:#ccc;border-color:transparent}.next-calendar-fullscreen .next-calendar-cell-current .next-calendar-date,.next-calendar-fullscreen .next-calendar-cell-current .next-calendar-month{font-weight:700;background:#fff;color:#209bfa;border-color:#209bfa}.next-calendar-card .next-calendar-th,.next-calendar-panel .next-calendar-th,.next-calendar-range .next-calendar-th{text-align:center;color:#999;font-size:12px;font-weight:400}.next-calendar-card .next-calendar-cell,.next-calendar-panel .next-calendar-cell,.next-calendar-range .next-calendar-cell{text-align:center;font-size:12px}.next-calendar-card .next-calendar-cell.next-selected .next-calendar-date,.next-calendar-card .next-calendar-cell.next-selected .next-calendar-month,.next-calendar-card .next-calendar-cell.next-selected .next-calendar-year,.next-calendar-panel .next-calendar-cell.next-selected .next-calendar-date,.next-calendar-panel .next-calendar-cell.next-selected .next-calendar-month,.next-calendar-panel .next-calendar-cell.next-selected .next-calendar-year,.next-calendar-range .next-calendar-cell.next-selected .next-calendar-date,.next-calendar-range .next-calendar-cell.next-selected .next-calendar-month,.next-calendar-range .next-calendar-cell.next-selected .next-calendar-year{animation:cellZoomIn .4s cubic-bezier(.23,1,.32,1);font-weight:700;background:#209bfa;color:#fff;border-color:#209bfa}.next-calendar-card .next-calendar-cell.next-disabled .next-calendar-date,.next-calendar-card .next-calendar-cell.next-disabled .next-calendar-month,.next-calendar-card .next-calendar-cell.next-disabled .next-calendar-year,.next-calendar-panel .next-calendar-cell.next-disabled .next-calendar-date,.next-calendar-panel .next-calendar-cell.next-disabled .next-calendar-month,.next-calendar-panel .next-calendar-cell.next-disabled .next-calendar-year,.next-calendar-range .next-calendar-cell.next-disabled .next-calendar-date,.next-calendar-range .next-calendar-cell.next-disabled .next-calendar-month,.next-calendar-range .next-calendar-cell.next-disabled .next-calendar-year{cursor:not-allowed;background:#fafafa;color:#ccc;border-color:#fafafa}.next-calendar-card .next-calendar-cell.next-inrange .next-calendar-date,.next-calendar-panel .next-calendar-cell.next-inrange .next-calendar-date,.next-calendar-range .next-calendar-cell.next-inrange .next-calendar-date{background:#e4f3fe;color:#209bfa;border-color:#e4f3fe}.next-calendar-card .next-calendar-date,.next-calendar-card .next-calendar-month,.next-calendar-card .next-calendar-year,.next-calendar-panel .next-calendar-date,.next-calendar-panel .next-calendar-month,.next-calendar-panel .next-calendar-year,.next-calendar-range .next-calendar-date,.next-calendar-range .next-calendar-month,.next-calendar-range .next-calendar-year{text-align:center;background:#fff;color:#666;border:1px solid #fff}.next-calendar-card .next-calendar-date:hover,.next-calendar-card .next-calendar-month:hover,.next-calendar-card .next-calendar-year:hover,.next-calendar-panel .next-calendar-date:hover,.next-calendar-panel .next-calendar-month:hover,.next-calendar-panel .next-calendar-year:hover,.next-calendar-range .next-calendar-date:hover,.next-calendar-range .next-calendar-month:hover,.next-calendar-range .next-calendar-year:hover{cursor:pointer;background:#e4f3fe;color:#209bfa;border-color:#e4f3fe}.next-calendar-card .next-calendar-date,.next-calendar-panel .next-calendar-date,.next-calendar-range .next-calendar-date{width:24px;height:24px;line-height:22px;margin:4px auto;border-radius:3px}.next-calendar-card .next-calendar-month,.next-calendar-panel .next-calendar-month,.next-calendar-range .next-calendar-month{width:60px;height:24px;line-height:22px;margin:8px auto;border-radius:3px}.next-calendar-card .next-calendar-year,.next-calendar-panel .next-calendar-year,.next-calendar-range .next-calendar-year{width:48px;height:24px;line-height:22px;margin:8px auto;border-radius:3px}.next-calendar-card .next-calendar-cell-next-month .next-calendar-date,.next-calendar-card .next-calendar-cell-prev-month .next-calendar-date,.next-calendar-panel .next-calendar-cell-next-month .next-calendar-date,.next-calendar-panel .next-calendar-cell-prev-month .next-calendar-date,.next-calendar-range .next-calendar-cell-next-month .next-calendar-date,.next-calendar-range .next-calendar-cell-prev-month .next-calendar-date{background:#fff;color:#ccc;border-color:#fff}.next-calendar-card .next-calendar-cell-current .next-calendar-date,.next-calendar-card .next-calendar-cell-current .next-calendar-month,.next-calendar-card .next-calendar-cell-current .next-calendar-year,.next-calendar-panel .next-calendar-cell-current .next-calendar-date,.next-calendar-panel .next-calendar-cell-current .next-calendar-month,.next-calendar-panel .next-calendar-cell-current .next-calendar-year,.next-calendar-range .next-calendar-cell-current .next-calendar-date,.next-calendar-range .next-calendar-cell-current .next-calendar-month,.next-calendar-range .next-calendar-cell-current .next-calendar-year{font-weight:700;background:#fff;color:#209bfa;border-color:transparent}.next-calendar-panel.next-calendar-week .next-calendar-tbody tr{cursor:pointer}.next-calendar-panel.next-calendar-week .next-calendar-tbody tr:hover .next-calendar-cell .next-calendar-date{background:#e4f3fe;color:#209bfa;border-color:#e4f3fe}.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-cell.next-selected .next-calendar-date{font-weight:400;background:transparent;border-color:transparent}.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-date{position:relative;color:#209bfa}.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-date:before{content:"";position:absolute;left:-1px;top:-1px;bottom:-1px;right:-1px;background:#e4f3fe;border:1px solid #e4f3fe;border-radius:3px}.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-date>span{position:relative}.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-end,.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-start{color:#fff}.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-end:before,.next-calendar-panel.next-calendar-week .next-calendar-tbody .next-calendar-week-active-start:before{background:#209bfa;border-color:#209bfa}.next-calendar[dir=rtl] .next-calendar-header{text-align:left}.next-calendar[dir=rtl] .next-calendar-header .next-select{margin-right:0;margin-left:4px}.next-calendar[dir=rtl] .next-calendar-header .next-menu{text-align:right}.next-calendar[dir=rtl] .next-calendar-btn-prev-decade,.next-calendar[dir=rtl] .next-calendar-btn-prev-year{left:auto;right:8px}.next-calendar[dir=rtl] .next-calendar-btn-prev-month{left:auto;right:28px}.next-calendar[dir=rtl] .next-calendar-btn-next-month{right:auto;left:28px}.next-calendar[dir=rtl] .next-calendar-btn-next-decade,.next-calendar[dir=rtl] .next-calendar-btn-next-year{right:auto;left:8px}.next-calendar-fullscreen[dir=rtl] .next-calendar-th{text-align:left;padding-left:12px;padding-right:0}.next-calendar-fullscreen[dir=rtl] .next-calendar-date,.next-calendar-fullscreen[dir=rtl] .next-calendar-month{text-align:left}.next-calendar-range[dir=rtl] .next-calendar-body-left,.next-calendar-range[dir=rtl] .next-calendar-body-right{float:right}.next-calendar-range[dir=rtl] .next-calendar-body-left{padding-right:0;padding-left:8px}.next-calendar-range[dir=rtl] .next-calendar-body-right{padding-left:0;padding-right:8px}.next-calendar-table{width:100%;table-layout:fixed}.next-calendar-range .next-calendar-body-left,.next-calendar-range .next-calendar-body-right{float:left;width:50%}.next-calendar-range .next-calendar-body-left{padding-right:8px}.next-calendar-range .next-calendar-body-right{padding-left:8px}.next-calendar-range .next-calendar-body:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-calendar-symbol-prev:before{content:""}.next-calendar-symbol-next:before{content:""}.next-calendar-symbol-prev-super:before{content:""}.next-calendar-symbol-next-super:before{content:""}.next-card,.next-card:after,.next-card:before{box-sizing:border-box}.next-card[dir=rtl] .next-card-extra{left:0;right:auto}.next-card[dir=rtl] .next-card-title:before{right:0;left:auto}.next-card[dir=rtl] .next-card-subtitle{float:left;padding-right:8px;padding-left:0}.next-card[dir=rtl] .next-card-head-show-bullet .next-card-title{padding-left:0;padding-right:8px}.next-card,.next-card *,.next-card :after,.next-card :before{box-sizing:border-box}.next-card{min-width:100px;border:0 solid #e6e6e6;border-radius:3px;box-shadow:none;background:#fff;overflow:hidden}.next-card-noborder{border:0}.next-card-head{background:#fff;padding-left:24px;padding-right:24px}.next-card-head-show-bullet .next-card-title{padding-left:8px}.next-card-head-show-bullet .next-card-title:before{content:"";display:inline-block;height:16px;width:3px;background:#209bfa;position:absolute;left:0;top:calc(50% - 8px)}.next-card-head-main{position:relative;margin-top:0;margin-bottom:0;height:64px;line-height:64px}.next-card-title{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:80%;height:100%;color:#333;font-size:16px;font-weight:400}.next-card-subtitle{font-size:12px;color:#666;padding-left:8px}.next-card-extra{position:absolute;right:0;top:0;height:100%;font-size:14px;color:#298dff}.next-card-body{padding-bottom:20px;padding-left:24px;padding-right:24px}.next-card-show-divider>.next-card-head>.next-card-head-main{border-bottom:1px solid #eee}.next-card-show-divider>.next-card-body{padding-top:20px}.next-card-hide-divider>.next-card-body{padding-top:0}.next-card-free{padding:0}.next-card-content{overflow:hidden;transition:all .3s ease;position:relative}.next-card-footer .next-icon{transition:all .1s linear}.next-card-footer .next-icon.next-icon-arrow-down.expand{transform-origin:50% 47%;transform:rotate(180deg)}.next-card-header{background:#fff;padding:0 24px;margin-bottom:20px;margin-top:20px}.next-card-media,.next-card-media>*{display:block;background-size:cover;background-repeat:no-repeat;background-position:50%;object-fit:cover;width:100%}.next-card-header-titles{overflow:hidden}.next-card-header-extra{float:right;text-align:right}.next-card-header-extra .next--btn{margin-left:12px;vertical-align:middle}.next-card-header-title{color:#333;font-size:16px;font-weight:400;line-height:1.5}.next-card-header-subtitle{font-size:12px;color:#666}.next-card-actions{display:block;padding:20px 24px}.next-card-actions .next-btn:not(:last-child){margin-right:12px;vertical-align:middle}.next-card-divider{border-style:none;width:100%;margin:0;position:relative;overflow:visible}.next-card-divider:before{content:"";display:block;border-bottom:1px solid #eee}.next-card-divider--inset{padding:0 24px}.next-card-content-container{margin-top:20px;padding-bottom:20px;padding-left:24px;padding-right:24px;font-size:14px;line-height:1.5;color:#666}.next-cascader{display:inline-block;overflow:auto;border:1px solid #e6e6e6;border-radius:3px}.next-cascader,.next-cascader *,.next-cascader :after,.next-cascader :before{box-sizing:border-box}.next-cascader-inner:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-cascader-menu-wrapper{float:left;overflow:auto;width:auto;min-width:100px;height:192px;overflow-x:hidden;overflow-y:auto}.next-cascader-menu-wrapper+.next-cascader-menu-wrapper{border-left:1px solid #e6e6e6}.next-cascader-menu{position:relative;padding:0;border:none;border-radius:0;box-shadow:none;min-width:auto;min-height:100%}.next-cascader-menu.next-has-right-border{border-right:1px solid #e6e6e6}.next-cascader-menu-item.next-expanded{color:#333;background-color:#f9f9f9}.next-cascader-menu-icon-right{position:absolute;top:0;right:10px;color:#666}.next-cascader-menu-icon-right:hover{color:#333}.next-cascader-menu-icon-expand.next-icon .next-icon-remote,.next-cascader-menu-icon-expand.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-cascader-menu-icon-loading.next-icon .next-icon-remote,.next-cascader-menu-icon-loading.next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-cascader-menu-item.next-expanded .next-cascader-menu-icon-right{color:#333}.next-cascader-menu-item.next-expanded .next-cascader-menu-icon-loading{color:#209bfa}.next-cascader-filtered-list{height:192px;padding:0;border:none;border-radius:0;box-shadow:none;overflow:auto}.next-cascader-filtered-list .next-menu-item-inner{overflow:visible}.next-cascader-filtered-item em{color:#209bfa;font-style:normal}.next-cascader[dir=rtl] .next-cascader-menu-wrapper{float:right;border-left:none;border-right:1px solid #e6e6e6}.next-cascader[dir=rtl] .next-cascader-menu-wrapper:first-child{border-right:none}.next-cascader[dir=rtl] .next-cascader-menu.next-has-right-border{border-right:none;border-left:1px solid #e6e6e6}.next-cascader[dir=rtl] .next-cascader-menu-icon-right{right:auto;left:10px}.next-cascader-select,.next-cascader-select *,.next-cascader-select :after,.next-cascader-select :before{box-sizing:border-box}.next-cascader-select-dropdown{box-sizing:border-box;border:1px solid #e6e6e6;border-radius:3px;box-shadow:none}.next-cascader-select-dropdown *,.next-cascader-select-dropdown :after,.next-cascader-select-dropdown :before{box-sizing:border-box}.next-cascader-select-dropdown .next-cascader{display:block;border:none;box-shadow:none}.next-cascader-select-not-found{padding:0;border:none;box-shadow:none;overflow:auto;color:#999}.next-cascader-select-not-found .next-menu-item:hover{color:#999;background:#fff;cursor:default}.next-checkbox-wrapper[dir=rtl]{margin-right:8px;margin-left:0}.next-checkbox-wrapper[dir=rtl]:first-child{margin-right:0}.next-checkbox-wrapper[dir=rtl]>.next-checkbox-label{margin-right:4px;margin-left:0}.next-checkbox-wrapper{box-sizing:border-box;display:inline-block}.next-checkbox-wrapper *,.next-checkbox-wrapper :after,.next-checkbox-wrapper :before{box-sizing:border-box}.next-checkbox-wrapper .next-checkbox{display:inline-block;position:relative;line-height:1;vertical-align:middle}.next-checkbox-wrapper input[type=checkbox]{opacity:0;position:absolute;top:0;left:0;width:16px;height:16px;margin:0;cursor:pointer}.next-checkbox-wrapper .next-checkbox-inner{display:block;width:16px;height:16px;background:#fff;border-radius:3px;border:1px solid #ddd;transition:all .1s linear;text-align:left;box-shadow:none}.next-checkbox-wrapper .next-checkbox-inner>.next-icon{transform:scale(0);position:absolute;top:0;opacity:0;line-height:16px;transition:all .1s linear;color:#fff;left:2px;margin-left:0}.next-checkbox-wrapper .next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper .next-checkbox-inner>.next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-checkbox-wrapper .next-checkbox-inner>.next-icon:before{vertical-align:top;margin-top:0}.next-checkbox-wrapper .next-checkbox-inner>.next-checkbox-select-icon:before{content:""}.next-checkbox-wrapper .next-checkbox-inner>.next-checkbox-semi-select-icon:before{content:""}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner{border-color:transparent;background-color:#209bfa}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner.hovered,.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner:hover,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner.hovered,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner:hover{border-color:transparent}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon{opacity:1;transform:scale(1);margin-left:0}.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.checked.focused>.next-checkbox>.next-checkbox-inner>.next-icon:before,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.checked>.next-checkbox>.next-checkbox-inner>.next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner{border-color:transparent;background-color:#209bfa}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner.hovered,.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner:hover,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner.hovered,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner:hover{border-color:transparent}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon{opacity:1;transform:scaleX(1);margin-left:0}.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.indeterminate.focused>.next-checkbox>.next-checkbox-inner>.next-icon:before,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon .next-icon-remote,.next-checkbox-wrapper.indeterminate>.next-checkbox>.next-checkbox-inner>.next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-checkbox-wrapper.focused>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper.hovered>.next-checkbox>.next-checkbox-inner,.next-checkbox-wrapper:not(.disabled):hover>.next-checkbox>.next-checkbox-inner{border-color:#209bfa;background-color:#add9ff}.next-checkbox-wrapper.focused .next-checkbox-label,.next-checkbox-wrapper.hovered .next-checkbox-label,.next-checkbox-wrapper:not(.disabled):hover .next-checkbox-label{cursor:pointer}.next-checkbox-wrapper.checked:not(.disabled).hovered>.next-checkbox .next-checkbox-inner,.next-checkbox-wrapper.checked:not(.disabled):hover>.next-checkbox .next-checkbox-inner,.next-checkbox-wrapper.indeterminate:not(.disabled).hovered>.next-checkbox .next-checkbox-inner,.next-checkbox-wrapper.indeterminate:not(.disabled):hover>.next-checkbox .next-checkbox-inner{border-color:transparent;background-color:#1274e7}.next-checkbox-wrapper.checked:not(.disabled).hovered>.next-checkbox .next-checkbox-inner>.next-icon,.next-checkbox-wrapper.checked:not(.disabled):hover>.next-checkbox .next-checkbox-inner>.next-icon,.next-checkbox-wrapper.indeterminate:not(.disabled).hovered>.next-checkbox .next-checkbox-inner>.next-icon,.next-checkbox-wrapper.indeterminate:not(.disabled):hover>.next-checkbox .next-checkbox-inner>.next-icon{color:#fff;opacity:1}.next-checkbox-wrapper.disabled input[type=checkbox]{cursor:not-allowed}.next-checkbox-wrapper.disabled.checked .next-checkbox-inner,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner,.next-checkbox-wrapper.disabled .next-checkbox-inner{border-color:#eee;background:#fafafa}.next-checkbox-wrapper.disabled.checked .next-checkbox-inner.hovered,.next-checkbox-wrapper.disabled.checked .next-checkbox-inner:hover,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner.hovered,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner:hover{border-color:#eee}.next-checkbox-wrapper.disabled.checked .next-checkbox-inner>.next-icon,.next-checkbox-wrapper.disabled.indeterminate .next-checkbox-inner>.next-icon{color:#ccc;opacity:1}.next-checkbox-wrapper.disabled.checked.focused .next-checkbox-inner{border-color:#eee;background:#fafafa}.next-checkbox-wrapper.disabled.checked.focused .next-checkbox-inner>.next-icon{color:#ccc;opacity:1}.next-checkbox-wrapper.disabled .next-checkbox-label{color:#ccc;cursor:not-allowed}.next-checkbox-group .next-checkbox-wrapper{display:inline-block;margin-right:12px}.next-checkbox-group .next-checkbox-wrapper:last-child{margin-right:0}.next-checkbox-group-ver .next-checkbox-wrapper{display:block;margin-left:0;margin-right:0;margin-bottom:8px}.next-checkbox-label{font-size:14px;color:#333;vertical-align:middle;margin:0 4px;line-height:1}.next-collapse[dir=rtl] .next-collapse-panel-title{padding:8px 36px 8px 0}.next-collapse[dir=rtl] .next-collapse-panel-icon{left:inherit;right:12px;transform:rotate(180deg);margin-left:0;margin-right:0}.next-collapse[dir=rtl] .next-collapse-panel-icon .next-icon-remote,.next-collapse[dir=rtl] .next-collapse-panel-icon:before{width:16px;font-size:16px;line-height:inherit}.next-collapse{border:1px solid #e6e6e6;border-radius:3px}.next-collapse,.next-collapse *,.next-collapse :after,.next-collapse :before{box-sizing:border-box}.next-collapse:focus,.next-collapse :focus{outline:0}.next-collapse-panel:not(:first-child){border-top:1px solid #e6e6e6}.next-collapse .next-collapse-panel-icon{position:absolute;color:#333;transition:transform .1s linear;left:12px;margin-top:-2px;margin-left:0;margin-right:0}.next-collapse .next-collapse-panel-icon .next-icon-remote,.next-collapse .next-collapse-panel-icon:before{width:16px;font-size:16px;line-height:inherit}.next-collapse-panel-title{position:relative;line-height:1.5;background:#f9f9f9;font-size:14px;font-weight:400;color:#333;cursor:pointer;padding:8px 0 8px 36px;transition:background .1s linear}.next-collapse-panel-title:hover{background:#f5f5f5;color:#333;font-weight:400}.next-collapse-panel-title:hover .next-collapse-panel-icon{color:#333}.next-collapse-panel-content{height:0;line-height:1.5;padding:0 16px;background:#fff;font-size:14px;color:#666;transition:all .3s ease;opacity:0}.next-collapse-panel-expanded>.next-collapse-panel-content{display:block;padding:12px 16px;height:auto;opacity:1}.next-collapse .next-collapse-unfold-icon:before{content:""}.next-collapse-panel-hidden>.next-collapse-panel-content{overflow:hidden}.next-collapse .next-collapse-panel-icon:before{content:""}.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded{transform:rotate(90deg);margin-left:0;margin-right:0}.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded .next-icon-remote,.next-collapse .next-collapse-panel-icon.next-collapse-panel-icon-expanded:before{width:16px;font-size:16px;line-height:inherit}.next-collapse-disabled,.next-collapse-panel-disabled:not(:first-child){border-color:#eee}.next-collapse-panel-disabled>.next-collapse-panel-title{cursor:not-allowed;color:#ccc;background:#f9f9f9}.next-collapse-panel-disabled .next-collapse-panel-icon{color:#ccc}.next-collapse-panel-disabled .next-collapse-panel-title:hover{font-weight:400}.next-collapse-panel-disabled .next-collapse-panel-title:hover .next-collapse-panel-icon{color:#ccc}.next-collapse-panel-disabled:hover{color:#ccc;background:#f9f9f9}.next-time-picker-menu{float:left;text-align:center}.next-time-picker-menu:not(:last-child){border-right:1px solid #ddd}.next-time-picker-menu-title{cursor:default;height:28px;line-height:28px;font-size:12px;font-weight:400;color:#999;background:#fff}.next-time-picker-menu ul{position:relative;overflow-y:auto;list-style:none;margin:0;padding:0;font-size:12px;height:196px}.next-time-picker-menu-item{cursor:pointer;height:28px;line-height:28px;transition:background .1s linear;color:#666;background:#fff;outline:none}.next-time-picker-menu-item:hover{color:#333;background:#f9f9f9}.next-time-picker-menu-item.next-selected{font-weight:700;color:#666;background:#f9f9f9}.next-time-picker-menu-item.next-disabled{cursor:not-allowed;color:#ccc;background:#fff}.next-time-picker-panel,.next-time-picker-panel *,.next-time-picker-panel :after,.next-time-picker-panel :before{box-sizing:border-box}.next-time-picker-panel:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-time-picker-panel-header{border-bottom:1px solid #e6e6e6}.next-time-picker-panel-input.next-input{width:100%;padding:6px;border-color:transparent;vertical-align:middle}.next-time-picker-panel-col-3 .next-time-picker-menu{width:33.3333333333%}.next-time-picker-panel-col-2 .next-time-picker-menu{width:50%}.next-time-picker-panel-col-1 .next-time-picker-menu{width:100%}.next-time-picker-body[dir=rtl] .next-time-picker-menu{float:right}.next-time-picker-body[dir=rtl] .next-time-picker-menu:not(:last-child){border-right:none;border-left:1px solid #ddd}.next-time-picker{display:inline-block;width:200px}.next-time-picker,.next-time-picker *,.next-time-picker :after,.next-time-picker :before{box-sizing:border-box}.next-time-picker-trigger .next-input{width:100%}.next-time-picker-body{overflow:hidden;width:200px;border:1px solid #e6e6e6;border-radius:3px;background:#fff;box-shadow:none}.next-time-picker-symbol-clock-icon:before{content:""}.next-range-picker-panel-input-separator,.next-range-picker-trigger-separator{cursor:default;display:inline-block;text-align:center;color:#ccc;width:16px;font-size:12px;vertical-align:middle}.next-date-picker,.next-month-picker,.next-week-picker,.next-year-picker{display:inline-block;width:200px}.next-date-picker-input,.next-month-picker-input,.next-week-picker-input,.next-year-picker-input{width:100%}.next-date-picker-body,.next-month-picker-body,.next-week-picker-body,.next-year-picker-body{width:288px}.next-date-picker-panel-input.next-input,.next-month-picker-panel-input.next-input,.next-week-picker-panel-input.next-input,.next-year-picker-panel-input.next-input{width:100%;background:transparent}.next-date-picker-body.next-date-picker-body-show-time .next-date-picker-panel-input.next-input{width:49%}.next-date-picker-body.next-date-picker-body-show-time .next-date-picker-panel-input.next-input:first-child{margin-right:2%}.next-range-picker{display:inline-block;width:336px}.next-range-picker-input{width:100%}.next-range-picker-trigger{border:1px solid #ddd;background-color:#fff}.next-range-picker-trigger:hover{border-color:#ccc;background-color:#fff}.next-range-picker-trigger.next-error{border-color:#d23c26}.next-range-picker-trigger-input.next-input{height:auto;width:calc(50% - 8px)}.next-range-picker.next-disabled .next-range-picker-trigger{color:#ccc;border-color:#eee;background-color:#fafafa;cursor:not-allowed}.next-range-picker.next-disabled .next-range-picker-trigger:hover{border-color:#eee;background-color:#fafafa}.next-range-picker.next-large .next-range-picker-panel-input,.next-range-picker.next-large .next-range-picker-trigger,.next-range-picker.next-medium .next-range-picker-panel-input,.next-range-picker.next-medium .next-range-picker-trigger,.next-range-picker.next-small .next-range-picker-panel-input,.next-range-picker.next-small .next-range-picker-trigger{border-radius:3px}.next-range-picker-body{width:600px}.next-range-picker-panel-input-end-date.next-input,.next-range-picker-panel-input-start-date.next-input{width:calc(50% - 8px)}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-input-end-date,.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-input-end-time,.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-input-start-date,.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-input-start-time{width:calc(25% - 8px)}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-input-start-date{margin-right:8px}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-input-end-time{margin-left:8px}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-time:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-time-end,.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-time-start{width:50%;float:left}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-time-start{border-right:1px solid #e6e6e6}.next-range-picker-body.next-range-picker-body-show-time .next-range-picker-panel-time-end{border-left:1px solid #e6e6e6}.next-date-picker-body[dir=rtl] .next-date-picker-panel-footer{text-align:left}.next-date-picker-body[dir=rtl] .next-date-picker-panel-footer>.next-btn:not(:last-child){margin-right:0;margin-left:16px}.next-date-picker-body[dir=rtl].next-date-picker-body-show-time .next-date-picker-panel-input.next-input:first-child{margin-left:2%;margin-right:0}.next-date-picker-body[dir=rtl].next-date-picker-body-show-time .next-time-picker-menu{float:right}.next-date-picker-body[dir=rtl].next-date-picker-body-show-time .next-time-picker-menu:not(:last-child){border-right:none;border-left:1px solid #ddd}.next-range-picker-body[dir=rtl] .next-range-picker-panel-input{text-align:right}.next-range-picker-body[dir=rtl] .next-date-picker-panel-footer{text-align:left}.next-range-picker-body[dir=rtl] .next-date-picker-panel-footer>.next-btn:not(:last-child){margin-right:0;margin-left:16px}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-range-picker-panel-input-start-date{margin-right:0;margin-left:8px}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-range-picker-panel-input-end-time{margin-left:0;margin-right:8px}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-range-picker-panel-time-end,.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-range-picker-panel-time-start{float:right}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-range-picker-panel-time-start{border-right:none;border-left:1px solid #e6e6e6}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-range-picker-panel-time-end{border-left:none;border-right:1px solid #e6e6e6}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-time-picker-menu{float:right}.next-range-picker-body[dir=rtl].next-range-picker-body-show-time .next-time-picker-menu:not(:last-child){border-right:none;border-left:1px solid #ddd}.next-date-picker,.next-date-picker *,.next-date-picker :after,.next-date-picker :before,.next-month-picker,.next-month-picker *,.next-month-picker :after,.next-month-picker :before,.next-range-picker,.next-range-picker *,.next-range-picker :after,.next-range-picker :before,.next-week-picker,.next-week-picker *,.next-week-picker :after,.next-week-picker :before,.next-year-picker,.next-year-picker *,.next-year-picker :after,.next-year-picker :before{box-sizing:border-box}.next-date-picker-body,.next-month-picker-body,.next-range-picker-body,.next-week-picker-body,.next-year-picker-body{border:1px solid #e6e6e6;border-radius:3px;box-shadow:none;background:#fff}.next-date-picker-panel-header,.next-month-picker-panel-header,.next-range-picker-panel-header,.next-week-picker-panel-header,.next-year-picker-panel-header{padding:6px;text-align:center}.next-date-picker-panel-time,.next-month-picker-panel-time,.next-range-picker-panel-time,.next-week-picker-panel-time,.next-year-picker-panel-time{border-top:1px solid #e6e6e6}.next-date-picker-panel-footer,.next-month-picker-panel-footer,.next-range-picker-panel-footer,.next-week-picker-panel-footer,.next-year-picker-panel-footer{text-align:right;padding:8px 20px;border-top:1px solid #e6e6e6}.next-date-picker-panel-footer>.next-btn:not(:last-child),.next-date-picker-panel-tools>.next-btn:not(:last-child),.next-month-picker-panel-footer>.next-btn:not(:last-child),.next-month-picker-panel-tools>.next-btn:not(:last-child),.next-range-picker-panel-footer>.next-btn:not(:last-child),.next-range-picker-panel-tools>.next-btn:not(:last-child),.next-week-picker-panel-footer>.next-btn:not(:last-child),.next-week-picker-panel-tools>.next-btn:not(:last-child),.next-year-picker-panel-footer>.next-btn:not(:last-child),.next-year-picker-panel-tools>.next-btn:not(:last-child){margin-right:16px}.next-date-picker-panel-tools,.next-month-picker-panel-tools,.next-range-picker-panel-tools,.next-week-picker-panel-tools,.next-year-picker-panel-tools{float:left}.next-date-picker .next-calendar-panel-header,.next-month-picker .next-calendar-panel-header,.next-range-picker .next-calendar-panel-header,.next-week-picker .next-calendar-panel-header,.next-year-picker .next-calendar-panel-header{margin-left:-1px;margin-right:-1px}.next-date-picker .next-input input,.next-month-picker .next-input input,.next-range-picker .next-input input,.next-week-picker .next-input input,.next-year-picker .next-input input{vertical-align:baseline}.next-date-picker-symbol-calendar-icon:before,.next-month-picker-symbol-calendar-icon:before,.next-range-picker-symbol-calendar-icon:before,.next-week-picker-symbol-calendar-icon:before,.next-year-picker-symbol-calendar-icon:before{content:""}.next-range-picker-panel-body .next-calendar{display:inline-block;width:50%}.next-message{position:relative;display:block;vertical-align:baseline;animation-duration:.3s;animation-timing-function:ease-in-out}.next-message,.next-message *,.next-message :after,.next-message :before{box-sizing:border-box}.next-message:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-message .next-message-close{color:#999;font-size:0;position:absolute;cursor:pointer}.next-message .next-message-close .next-icon-close{width:12px;height:12px;line-height:1em}.next-message .next-message-close .next-icon-close:before{width:12px;height:12px;font-size:12px;line-height:1em}.next-message .next-message-close:hover{color:#666}.next-message.next-message-success.next-inline{background-color:#e5fff5;border-color:#e5fff5;box-shadow:none;border-style:solid}.next-message.next-message-success.next-inline .next-message-title{color:#333}.next-message.next-message-success.next-inline .next-message-content{color:#666}.next-message.next-message-success.next-inline .next-message-symbol{color:#1ad78c}.next-message.next-message-success.next-inline .next-message-symbol-icon:before{content:""}.next-message.next-message-success.next-addon{background-color:transparent;border-color:transparent;box-shadow:none;border-style:solid}.next-message.next-message-success.next-addon .next-message-title{color:#333}.next-message.next-message-success.next-addon .next-message-content{color:#666}.next-message.next-message-success.next-addon .next-message-symbol{color:#1ad78c}.next-message.next-message-success.next-addon .next-message-symbol-icon:before{content:""}.next-message.next-message-success.next-toast{background-color:#fff;border-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-style:solid}.next-message.next-message-success.next-toast .next-message-title{color:#333}.next-message.next-message-success.next-toast .next-message-content{color:#666}.next-message.next-message-success.next-toast .next-message-symbol{color:#1ad78c}.next-message.next-message-success.next-toast .next-message-symbol-icon:before{content:""}.next-message.next-message-warning.next-inline{background-color:#fff9e0;border-color:#fff9e0;box-shadow:none;border-style:solid}.next-message.next-message-warning.next-inline .next-message-title{color:#333}.next-message.next-message-warning.next-inline .next-message-content{color:#666}.next-message.next-message-warning.next-inline .next-message-symbol{color:#f1c826}.next-message.next-message-warning.next-inline .next-message-symbol-icon:before{content:""}.next-message.next-message-warning.next-addon{background-color:transparent;border-color:transparent;box-shadow:none;border-style:solid}.next-message.next-message-warning.next-addon .next-message-title{color:#333}.next-message.next-message-warning.next-addon .next-message-content{color:#666}.next-message.next-message-warning.next-addon .next-message-symbol{color:#f1c826}.next-message.next-message-warning.next-addon .next-message-symbol-icon:before{content:""}.next-message.next-message-warning.next-toast{background-color:#fff;border-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-style:solid}.next-message.next-message-warning.next-toast .next-message-title{color:#333}.next-message.next-message-warning.next-toast .next-message-content{color:#666}.next-message.next-message-warning.next-toast .next-message-symbol{color:#f1c826}.next-message.next-message-warning.next-toast .next-message-symbol-icon:before{content:""}.next-message.next-message-error.next-inline{background-color:#ffece4;border-color:#ffece4;box-shadow:none;border-style:solid}.next-message.next-message-error.next-inline .next-message-title{color:#333}.next-message.next-message-error.next-inline .next-message-content{color:#666}.next-message.next-message-error.next-inline .next-message-symbol{color:#d23c26}.next-message.next-message-error.next-inline .next-message-symbol-icon:before{content:""}.next-message.next-message-error.next-addon{background-color:transparent;border-color:transparent;box-shadow:none;border-style:solid}.next-message.next-message-error.next-addon .next-message-title{color:#333}.next-message.next-message-error.next-addon .next-message-content{color:#666}.next-message.next-message-error.next-addon .next-message-symbol{color:#d23c26}.next-message.next-message-error.next-addon .next-message-symbol-icon:before{content:""}.next-message.next-message-error.next-toast{background-color:#fff;border-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-style:solid}.next-message.next-message-error.next-toast .next-message-title{color:#333}.next-message.next-message-error.next-toast .next-message-content{color:#666}.next-message.next-message-error.next-toast .next-message-symbol{color:#d23c26}.next-message.next-message-error.next-toast .next-message-symbol-icon:before{content:""}.next-message.next-message-notice.next-inline{background-color:#e4f3fe;border-color:#e4f3fe;box-shadow:none;border-style:solid}.next-message.next-message-notice.next-inline .next-message-title{color:#333}.next-message.next-message-notice.next-inline .next-message-content{color:#666}.next-message.next-message-notice.next-inline .next-message-symbol{color:#298dff}.next-message.next-message-notice.next-inline .next-message-symbol-icon:before{content:""}.next-message.next-message-notice.next-addon{background-color:transparent;border-color:transparent;box-shadow:none;border-style:solid}.next-message.next-message-notice.next-addon .next-message-title{color:#333}.next-message.next-message-notice.next-addon .next-message-content{color:#666}.next-message.next-message-notice.next-addon .next-message-symbol{color:#298dff}.next-message.next-message-notice.next-addon .next-message-symbol-icon:before{content:""}.next-message.next-message-notice.next-toast{background-color:#fff;border-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-style:solid}.next-message.next-message-notice.next-toast .next-message-title{color:#333}.next-message.next-message-notice.next-toast .next-message-content{color:#666}.next-message.next-message-notice.next-toast .next-message-symbol{color:#298dff}.next-message.next-message-notice.next-toast .next-message-symbol-icon:before{content:""}.next-message.next-message-help.next-inline{background-color:#fff9e0;border-color:#fff9e0;box-shadow:none;border-style:solid}.next-message.next-message-help.next-inline .next-message-title{color:#333}.next-message.next-message-help.next-inline .next-message-content{color:#666}.next-message.next-message-help.next-inline .next-message-symbol{color:#f1c826}.next-message.next-message-help.next-inline .next-message-symbol-icon:before{content:""}.next-message.next-message-help.next-addon{background-color:transparent;border-color:transparent;box-shadow:none;border-style:solid}.next-message.next-message-help.next-addon .next-message-title{color:#333}.next-message.next-message-help.next-addon .next-message-content{color:#666}.next-message.next-message-help.next-addon .next-message-symbol{color:#f1c826}.next-message.next-message-help.next-addon .next-message-symbol-icon:before{content:""}.next-message.next-message-help.next-toast{background-color:#fff;border-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-style:solid}.next-message.next-message-help.next-toast .next-message-title{color:#333}.next-message.next-message-help.next-toast .next-message-content{color:#666}.next-message.next-message-help.next-toast .next-message-symbol{color:#f1c826}.next-message.next-message-help.next-toast .next-message-symbol-icon:before{content:""}.next-message.next-message-loading.next-inline{background-color:#fff;border-color:#fff;box-shadow:none;border-style:solid}.next-message.next-message-loading.next-inline .next-message-title{color:#333}.next-message.next-message-loading.next-inline .next-message-content{color:#666}.next-message.next-message-loading.next-inline .next-message-symbol{color:#209bfa}.next-message.next-message-loading.next-inline .next-message-symbol-icon:before{content:"";animation:loadingCircle 1s linear infinite}.next-message.next-message-loading.next-addon{background-color:transparent;border-color:transparent;box-shadow:none;border-style:solid}.next-message.next-message-loading.next-addon .next-message-title{color:#333}.next-message.next-message-loading.next-addon .next-message-content{color:#666}.next-message.next-message-loading.next-addon .next-message-symbol{color:#209bfa}.next-message.next-message-loading.next-addon .next-message-symbol-icon:before{content:"";animation:loadingCircle 1s linear infinite}.next-message.next-message-loading.next-toast{background-color:#fff;border-color:#fff;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);border-style:solid}.next-message.next-message-loading.next-toast .next-message-title{color:#333}.next-message.next-message-loading.next-toast .next-message-content{color:#666}.next-message.next-message-loading.next-toast .next-message-symbol{color:#209bfa}.next-message.next-message-loading.next-toast .next-message-symbol-icon:before{content:"";animation:loadingCircle 1s linear infinite}.next-message.next-medium{border-width:1px;padding:12px}.next-message.next-medium .next-message-symbol{float:left;line-height:16px}.next-message.next-medium .next-message-symbol .next-icon-remote,.next-message.next-medium .next-message-symbol:before{width:16px;font-size:16px;line-height:inherit}.next-message.next-medium .next-message-title{padding:0 20px 0 24px;font-size:16px;line-height:16px}.next-message.next-medium .next-message-content{margin-top:8px;padding:0 20px 0 24px;font-size:14px;line-height:1.5}.next-message.next-medium .next-message-symbol+.next-message-content{margin-top:0}.next-message.next-medium.next-only-content .next-message-content,.next-message.next-medium.next-title-content .next-message-title{line-height:16px}.next-message.next-medium .next-message-close{top:12px;right:12px}.next-message.next-medium.next-inline,.next-message.next-medium.next-toast{border-radius:3px}.next-message.next-large{border-width:2px;padding:16px}.next-message.next-large .next-message-symbol{float:left;line-height:24px}.next-message.next-large .next-message-symbol .next-icon-remote,.next-message.next-large .next-message-symbol:before{width:24px;font-size:24px;line-height:inherit}.next-message.next-large .next-message-title{padding:0 20px 0 36px;font-size:20px;line-height:20px}.next-message.next-large .next-message-content{margin-top:8px;padding:0 20px 0 36px;font-size:14px;line-height:1.5}.next-message.next-large .next-message-symbol+.next-message-content{margin-top:0}.next-message.next-large.next-only-content .next-message-content,.next-message.next-large.next-title-content .next-message-title{line-height:24px}.next-message.next-large .next-message-close{top:16px;right:16px}.next-message.next-large.next-inline,.next-message.next-large.next-toast{border-radius:3px}.next-message[dir=rtl] .next-message-symbol{float:right}.next-message[dir=rtl].next-medium .next-message-title{padding:0 24px 0 20px}.next-message[dir=rtl].next-medium .next-message-close{left:12px;right:auto}.next-message[dir=rtl].next-large .next-message-title{padding:0 36px 0 20px}.next-message[dir=rtl].next-large .next-message-close{left:16px;right:auto}.next-message-wrapper-v2{margin:0;padding:0;position:fixed;left:0;z-index:1001;width:100%;pointer-events:none}.next-message-list{padding:8px;text-align:center}.next-message-list .next-message{display:inline-block;pointer-events:all}.next-message-fade-leave{animation-duration:.3s;animation-play-state:paused;animation-fill-mode:both;animation-timing-function:ease}.next-message-fade-leave.next-message-fade-leave-active{animation-name:MessageFadeOut;animation-play-state:running}@keyframes MessageFadeOut{0%{max-height:150px;margin-bottom:16px;opacity:1}to{max-height:0;margin-bottom:0;padding-top:0;padding-bottom:0;opacity:0}}.next-dialog[dir=rtl],.next-dialog[dir=rtl] .next-dialog-footer.next-align-left{text-align:right}.next-dialog[dir=rtl] .next-dialog-footer.next-align-center{text-align:center}.next-dialog[dir=rtl] .next-dialog-footer.next-align-right{text-align:left}.next-dialog[dir=rtl] .next-dialog-btn+.next-dialog-btn{margin-right:4px;margin-left:0}.next-dialog[dir=rtl] .next-dialog-close{left:12px;right:auto}.next-dialog{position:fixed;z-index:1001;background:#fff;border:1px solid #e6e6e6;border-radius:6px;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);text-align:left;overflow:hidden;max-width:90%}.next-dialog,.next-dialog *,.next-dialog :after,.next-dialog :before{box-sizing:border-box}.next-dialog-header{padding:12px 20px;border-bottom:0 solid transparent;font-size:16px;font-weight:400;background:transparent;color:#333}.next-dialog-body{padding:20px;font-size:14px;line-height:1.5;color:#666}.next-dialog-body-no-footer{margin-bottom:0}.next-dialog-body-no-padding{padding:0}.next-dialog-footer{padding:12px 20px;border-top:0 solid transparent;background:transparent}.next-dialog-footer.next-align-left{text-align:left}.next-dialog-footer.next-align-center{text-align:center}.next-dialog-footer.next-align-right{text-align:right}.next-dialog-footer-fixed-height{position:absolute;width:100%;bottom:0}.next-dialog-btn+.next-dialog-btn{margin-left:4px}.next-dialog-close{position:absolute;top:12px;right:12px;width:16px;cursor:pointer}.next-dialog-close,.next-dialog-close:link,.next-dialog-close:visited{height:16px;color:#999}.next-dialog-close:hover{background:transparent;color:#333}.next-dialog-close .next-dialog-close-icon.next-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px;width:16px;height:16px;line-height:1em}.next-dialog-close .next-dialog-close-icon.next-icon:before{width:16px;height:16px;font-size:16px;line-height:1em}.next-dialog-container{position:fixed;top:0;left:0;right:0;bottom:0;z-index:1001;padding:40px;overflow:auto;text-align:center;box-sizing:border-box}.next-dialog-container:before{display:inline-block;vertical-align:middle;width:0;height:100%;content:""}.next-dialog-container .next-dialog{display:inline-block;position:relative;vertical-align:middle}.next-dialog-quick .next-dialog-body{padding:20px}.next-dialog .next-dialog-message.next-message{min-width:300px;padding:0}.next-dialog-wrapper{position:fixed;top:0;left:0;bottom:0;right:0;overflow:auto}.next-dialog-inner-wrapper{display:flex;position:relative;top:100px;pointer-events:none;padding-bottom:24px}.next-dialog-v2{pointer-events:auto;margin:0 auto}.next-dialog-v2 .next-dialog-header{word-break:break-word;padding-right:40px}.next-dialog-v2 .next-dialog-body{padding-right:40px}.next-dialog-v2 .next-dialog-header+.next-dialog-body{padding:20px}.next-dialog-v2 .next-dialog-header+.next-dialog-body-no-footer{margin-bottom:0}.next-dialog-v2 .next-dialog-body.next-dialog-body-no-padding{padding:0}.next-dialog.next-dialog-v2{position:relative}.next-dialog-centered{text-align:center}.next-dialog-centered:before{display:inline-block;width:0;height:100%;vertical-align:middle;content:""}.next-dialog-centered .next-dialog-v2{margin:40px 0;display:inline-block;text-align:left;vertical-align:middle}.next-drawer{position:fixed;z-index:1001;background:#fff;border:1px solid #e6e6e6;box-shadow:0 4px 8px 0 rgba(0,0,0,.12);overflow:auto;animation-duration:.3s;animation-timing-function:ease-in-out}.next-drawer,.next-drawer *,.next-drawer :after,.next-drawer :before{box-sizing:border-box}.next-drawer-left,.next-drawer-right{height:100%;max-width:80%;width:240px}.next-drawer-bottom,.next-drawer-top{width:100%}.next-drawer-header{padding:12px 20px;border-bottom:1px solid #e6e6e6;font-size:16px;background:#fff;color:#333}.next-drawer-no-title{padding:0;border-bottom:0}.next-drawer-body{padding:20px;font-size:14px;line-height:1.5;color:#666}.next-drawer-close{position:absolute;top:12px;right:12px;width:16px;cursor:pointer}.next-drawer-close,.next-drawer-close:link,.next-drawer-close:visited{height:16px;color:#999}.next-drawer-close:hover{background:transparent;color:#333}.next-drawer-close .next-drawer-close-icon.next-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px;width:16px;height:16px;line-height:1em}.next-drawer-close .next-drawer-close-icon.next-icon:before{width:16px;height:16px;font-size:16px;line-height:1em}.next-drawer-wrapper{position:fixed}.next-drawer-wrapper .next-drawer-v2{position:static;width:100%;height:100%}.next-drawer-wrapper .next-drawer-content{display:flex;flex-flow:column nowrap;width:100%;height:100%}.next-drawer-wrapper .next-drawer-header{display:flex;align-items:center;justify-content:space-between}.next-drawer-wrapper .next-drawer-body{flex-grow:1;overflow:auto;word-wrap:break-word;font-size:14px}.next-drawer-wrapper.next-drawer-right{width:400px;right:0;top:0;height:100%}.next-drawer-wrapper.next-drawer-right .next-drawer-v2{height:100%}.next-drawer-wrapper.next-drawer-left{width:400px;left:0;top:0;height:100%}.next-drawer-wrapper.next-drawer-left .next-drawer-v2{height:100%}.next-drawer-wrapper.next-drawer-top{height:400px;left:0;top:0;width:100%}.next-drawer-wrapper.next-drawer-top .next-drawer-v2{width:100%}.next-drawer-wrapper.next-drawer-bottom{height:400px;left:0;bottom:0;width:100%}.next-drawer-wrapper.next-drawer-bottom .next-drawer-v2{width:100%}.next-row{display:flex}.next-row,.next-row *,.next-row :after,.next-row :before{box-sizing:border-box}.next-row.next-row-wrap{flex-wrap:wrap}@media(min-width:320px){.next-row.next-row-fixed{width:320px}}@media(min-width:480px){.next-row.next-row-fixed{width:480px}}@media(min-width:720px){.next-row.next-row-fixed{width:720px}}@media(min-width:990px){.next-row.next-row-fixed{width:990px}}@media(min-width:1200px){.next-row.next-row-fixed{width:1200px}}@media(min-width:1500px){.next-row.next-row-fixed{width:1500px}}.next-row.next-row-fixed-xxs{width:320px}.next-row.next-row-fixed-xs{width:480px}.next-row.next-row-fixed-s{width:720px}.next-row.next-row-fixed-m{width:990px}.next-row.next-row-fixed-l{width:1200px}.next-row.next-row-fixed-xl{width:1500px}.next-row.next-row-justify-start{justify-content:flex-start}.next-row.next-row-justify-end{justify-content:flex-end}.next-row.next-row-justify-center{justify-content:center}.next-row.next-row-justify-space-between{justify-content:space-between}.next-row.next-row-justify-space-around{justify-content:space-around}.next-row.next-row-align-top{align-items:flex-start}.next-row.next-row-align-bottom{align-items:flex-end}.next-row.next-row-align-center{align-items:center}.next-row.next-row-align-baseline{align-items:baseline}.next-row.next-row-align-stretch{align-items:stretch}.next-col{flex:1}.next-col.next-col-top{align-self:flex-start}.next-col.next-col-bottom{align-self:flex-end}.next-col.next-col-center{align-self:center}@media (min-width:0\0)and (min-resolution:0.001dpcm){.next-row{display:table;width:100%}.next-col{display:table-cell;vertical-align:top}}.next-col-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-24{flex:0 0 100%;width:100%;max-width:100%}@media(min-width:320px){.next-col-xxs-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-xxs-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-xxs-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-xxs-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-xxs-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-xxs-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-xxs-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-xxs-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-xxs-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-xxs-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-xxs-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-xxs-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-xxs-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-xxs-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-xxs-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-xxs-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-xxs-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-xxs-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-xxs-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-xxs-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-xxs-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-xxs-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-xxs-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-xxs-24{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:480px){.next-col-xs-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-xs-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-xs-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-xs-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-xs-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-xs-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-xs-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-xs-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-xs-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-xs-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-xs-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-xs-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-xs-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-xs-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-xs-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-xs-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-xs-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-xs-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-xs-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-xs-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-xs-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-xs-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-xs-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-xs-24{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:720px){.next-col-s-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-s-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-s-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-s-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-s-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-s-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-s-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-s-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-s-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-s-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-s-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-s-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-s-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-s-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-s-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-s-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-s-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-s-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-s-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-s-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-s-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-s-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-s-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-s-24{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:990px){.next-col-m-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-m-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-m-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-m-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-m-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-m-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-m-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-m-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-m-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-m-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-m-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-m-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-m-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-m-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-m-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-m-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-m-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-m-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-m-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-m-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-m-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-m-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-m-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-m-24{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:1200px){.next-col-l-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-l-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-l-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-l-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-l-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-l-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-l-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-l-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-l-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-l-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-l-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-l-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-l-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-l-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-l-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-l-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-l-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-l-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-l-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-l-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-l-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-l-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-l-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-l-24{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:1500px){.next-col-xl-1{flex:0 0 4.1666666667%;width:4.1666666667%;max-width:4.1666666667%}.next-col-xl-2{flex:0 0 8.3333333333%;width:8.3333333333%;max-width:8.3333333333%}.next-col-xl-3{flex:0 0 12.5%;width:12.5%;max-width:12.5%}.next-col-xl-4{flex:0 0 16.6666666667%;width:16.6666666667%;max-width:16.6666666667%}.next-col-xl-5{flex:0 0 20.8333333333%;width:20.8333333333%;max-width:20.8333333333%}.next-col-xl-6{flex:0 0 25%;width:25%;max-width:25%}.next-col-xl-7{flex:0 0 29.1666666667%;width:29.1666666667%;max-width:29.1666666667%}.next-col-xl-8{flex:0 0 33.3333333333%;width:33.3333333333%;max-width:33.3333333333%}.next-col-xl-9{flex:0 0 37.5%;width:37.5%;max-width:37.5%}.next-col-xl-10{flex:0 0 41.6666666667%;width:41.6666666667%;max-width:41.6666666667%}.next-col-xl-11{flex:0 0 45.8333333333%;width:45.8333333333%;max-width:45.8333333333%}.next-col-xl-12{flex:0 0 50%;width:50%;max-width:50%}.next-col-xl-13{flex:0 0 54.1666666667%;width:54.1666666667%;max-width:54.1666666667%}.next-col-xl-14{flex:0 0 58.3333333333%;width:58.3333333333%;max-width:58.3333333333%}.next-col-xl-15{flex:0 0 62.5%;width:62.5%;max-width:62.5%}.next-col-xl-16{flex:0 0 66.6666666667%;width:66.6666666667%;max-width:66.6666666667%}.next-col-xl-17{flex:0 0 70.8333333333%;width:70.8333333333%;max-width:70.8333333333%}.next-col-xl-18{flex:0 0 75%;width:75%;max-width:75%}.next-col-xl-19{flex:0 0 79.1666666667%;width:79.1666666667%;max-width:79.1666666667%}.next-col-xl-20{flex:0 0 83.3333333333%;width:83.3333333333%;max-width:83.3333333333%}.next-col-xl-21{flex:0 0 87.5%;width:87.5%;max-width:87.5%}.next-col-xl-22{flex:0 0 91.6666666667%;width:91.6666666667%;max-width:91.6666666667%}.next-col-xl-23{flex:0 0 95.8333333333%;width:95.8333333333%;max-width:95.8333333333%}.next-col-xl-24{flex:0 0 100%;width:100%;max-width:100%}}.next-col-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-5p5{flex:0 0 100%;width:100%;max-width:100%}@media(min-width:320px){.next-col-xxs-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-xxs-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-xxs-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-xxs-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-xxs-5p5{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:480px){.next-col-xs-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-xs-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-xs-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-xs-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-xs-5p5{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:720px){.next-col-s-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-s-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-s-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-s-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-s-5p5{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:990px){.next-col-m-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-m-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-m-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-m-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-m-5p5{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:1200px){.next-col-l-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-l-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-l-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-l-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-l-5p5{flex:0 0 100%;width:100%;max-width:100%}}@media(min-width:1500px){.next-col-xl-1p5{flex:0 0 20%;width:20%;max-width:20%}.next-col-xl-2p5{flex:0 0 40%;width:40%;max-width:40%}.next-col-xl-3p5{flex:0 0 60%;width:60%;max-width:60%}.next-col-xl-4p5{flex:0 0 80%;width:80%;max-width:80%}.next-col-xl-5p5{flex:0 0 100%;width:100%;max-width:100%}}.next-col-fixed-1{flex:0 0 20px;width:20px;max-width:20px}.next-col-fixed-2{flex:0 0 40px;width:40px;max-width:40px}.next-col-fixed-3{flex:0 0 60px;width:60px;max-width:60px}.next-col-fixed-4{flex:0 0 80px;width:80px;max-width:80px}.next-col-fixed-5{flex:0 0 100px;width:100px;max-width:100px}.next-col-fixed-6{flex:0 0 120px;width:120px;max-width:120px}.next-col-fixed-7{flex:0 0 140px;width:140px;max-width:140px}.next-col-fixed-8{flex:0 0 160px;width:160px;max-width:160px}.next-col-fixed-9{flex:0 0 180px;width:180px;max-width:180px}.next-col-fixed-10{flex:0 0 200px;width:200px;max-width:200px}.next-col-fixed-11{flex:0 0 220px;width:220px;max-width:220px}.next-col-fixed-12{flex:0 0 240px;width:240px;max-width:240px}.next-col-fixed-13{flex:0 0 260px;width:260px;max-width:260px}.next-col-fixed-14{flex:0 0 280px;width:280px;max-width:280px}.next-col-fixed-15{flex:0 0 300px;width:300px;max-width:300px}.next-col-fixed-16{flex:0 0 320px;width:320px;max-width:320px}.next-col-fixed-17{flex:0 0 340px;width:340px;max-width:340px}.next-col-fixed-18{flex:0 0 360px;width:360px;max-width:360px}.next-col-fixed-19{flex:0 0 380px;width:380px;max-width:380px}.next-col-fixed-20{flex:0 0 400px;width:400px;max-width:400px}.next-col-fixed-21{flex:0 0 420px;width:420px;max-width:420px}.next-col-fixed-22{flex:0 0 440px;width:440px;max-width:440px}.next-col-fixed-23{flex:0 0 460px;width:460px;max-width:460px}.next-col-fixed-24{flex:0 0 480px;width:480px;max-width:480px}.next-col-fixed-25{flex:0 0 500px;width:500px;max-width:500px}.next-col-fixed-26{flex:0 0 520px;width:520px;max-width:520px}.next-col-fixed-27{flex:0 0 540px;width:540px;max-width:540px}.next-col-fixed-28{flex:0 0 560px;width:560px;max-width:560px}.next-col-fixed-29{flex:0 0 580px;width:580px;max-width:580px}.next-col-fixed-30{flex:0 0 600px;width:600px;max-width:600px}.next-col-offset-1{margin-left:4.1666666667%}.next-col-offset-2{margin-left:8.3333333333%}.next-col-offset-3{margin-left:12.5%}.next-col-offset-4{margin-left:16.6666666667%}.next-col-offset-5{margin-left:20.8333333333%}.next-col-offset-6{margin-left:25%}.next-col-offset-7{margin-left:29.1666666667%}.next-col-offset-8{margin-left:33.3333333333%}.next-col-offset-9{margin-left:37.5%}.next-col-offset-10{margin-left:41.6666666667%}.next-col-offset-11{margin-left:45.8333333333%}.next-col-offset-12{margin-left:50%}.next-col-offset-13{margin-left:54.1666666667%}.next-col-offset-14{margin-left:58.3333333333%}.next-col-offset-15{margin-left:62.5%}.next-col-offset-16{margin-left:66.6666666667%}.next-col-offset-17{margin-left:70.8333333333%}.next-col-offset-18{margin-left:75%}.next-col-offset-19{margin-left:79.1666666667%}.next-col-offset-20{margin-left:83.3333333333%}.next-col-offset-21{margin-left:87.5%}.next-col-offset-22{margin-left:91.6666666667%}.next-col-offset-23{margin-left:95.8333333333%}.next-col-offset-24{margin-left:100%}@media(min-width:320px){.next-col-xxs-offset-1{margin-left:4.1666666667%}.next-col-xxs-offset-2{margin-left:8.3333333333%}.next-col-xxs-offset-3{margin-left:12.5%}.next-col-xxs-offset-4{margin-left:16.6666666667%}.next-col-xxs-offset-5{margin-left:20.8333333333%}.next-col-xxs-offset-6{margin-left:25%}.next-col-xxs-offset-7{margin-left:29.1666666667%}.next-col-xxs-offset-8{margin-left:33.3333333333%}.next-col-xxs-offset-9{margin-left:37.5%}.next-col-xxs-offset-10{margin-left:41.6666666667%}.next-col-xxs-offset-11{margin-left:45.8333333333%}.next-col-xxs-offset-12{margin-left:50%}.next-col-xxs-offset-13{margin-left:54.1666666667%}.next-col-xxs-offset-14{margin-left:58.3333333333%}.next-col-xxs-offset-15{margin-left:62.5%}.next-col-xxs-offset-16{margin-left:66.6666666667%}.next-col-xxs-offset-17{margin-left:70.8333333333%}.next-col-xxs-offset-18{margin-left:75%}.next-col-xxs-offset-19{margin-left:79.1666666667%}.next-col-xxs-offset-20{margin-left:83.3333333333%}.next-col-xxs-offset-21{margin-left:87.5%}.next-col-xxs-offset-22{margin-left:91.6666666667%}.next-col-xxs-offset-23{margin-left:95.8333333333%}.next-col-xxs-offset-24{margin-left:100%}}@media(min-width:480px){.next-col-xs-offset-1{margin-left:4.1666666667%}.next-col-xs-offset-2{margin-left:8.3333333333%}.next-col-xs-offset-3{margin-left:12.5%}.next-col-xs-offset-4{margin-left:16.6666666667%}.next-col-xs-offset-5{margin-left:20.8333333333%}.next-col-xs-offset-6{margin-left:25%}.next-col-xs-offset-7{margin-left:29.1666666667%}.next-col-xs-offset-8{margin-left:33.3333333333%}.next-col-xs-offset-9{margin-left:37.5%}.next-col-xs-offset-10{margin-left:41.6666666667%}.next-col-xs-offset-11{margin-left:45.8333333333%}.next-col-xs-offset-12{margin-left:50%}.next-col-xs-offset-13{margin-left:54.1666666667%}.next-col-xs-offset-14{margin-left:58.3333333333%}.next-col-xs-offset-15{margin-left:62.5%}.next-col-xs-offset-16{margin-left:66.6666666667%}.next-col-xs-offset-17{margin-left:70.8333333333%}.next-col-xs-offset-18{margin-left:75%}.next-col-xs-offset-19{margin-left:79.1666666667%}.next-col-xs-offset-20{margin-left:83.3333333333%}.next-col-xs-offset-21{margin-left:87.5%}.next-col-xs-offset-22{margin-left:91.6666666667%}.next-col-xs-offset-23{margin-left:95.8333333333%}.next-col-xs-offset-24{margin-left:100%}}@media(min-width:720px){.next-col-s-offset-1{margin-left:4.1666666667%}.next-col-s-offset-2{margin-left:8.3333333333%}.next-col-s-offset-3{margin-left:12.5%}.next-col-s-offset-4{margin-left:16.6666666667%}.next-col-s-offset-5{margin-left:20.8333333333%}.next-col-s-offset-6{margin-left:25%}.next-col-s-offset-7{margin-left:29.1666666667%}.next-col-s-offset-8{margin-left:33.3333333333%}.next-col-s-offset-9{margin-left:37.5%}.next-col-s-offset-10{margin-left:41.6666666667%}.next-col-s-offset-11{margin-left:45.8333333333%}.next-col-s-offset-12{margin-left:50%}.next-col-s-offset-13{margin-left:54.1666666667%}.next-col-s-offset-14{margin-left:58.3333333333%}.next-col-s-offset-15{margin-left:62.5%}.next-col-s-offset-16{margin-left:66.6666666667%}.next-col-s-offset-17{margin-left:70.8333333333%}.next-col-s-offset-18{margin-left:75%}.next-col-s-offset-19{margin-left:79.1666666667%}.next-col-s-offset-20{margin-left:83.3333333333%}.next-col-s-offset-21{margin-left:87.5%}.next-col-s-offset-22{margin-left:91.6666666667%}.next-col-s-offset-23{margin-left:95.8333333333%}.next-col-s-offset-24{margin-left:100%}}@media(min-width:990px){.next-col-m-offset-1{margin-left:4.1666666667%}.next-col-m-offset-2{margin-left:8.3333333333%}.next-col-m-offset-3{margin-left:12.5%}.next-col-m-offset-4{margin-left:16.6666666667%}.next-col-m-offset-5{margin-left:20.8333333333%}.next-col-m-offset-6{margin-left:25%}.next-col-m-offset-7{margin-left:29.1666666667%}.next-col-m-offset-8{margin-left:33.3333333333%}.next-col-m-offset-9{margin-left:37.5%}.next-col-m-offset-10{margin-left:41.6666666667%}.next-col-m-offset-11{margin-left:45.8333333333%}.next-col-m-offset-12{margin-left:50%}.next-col-m-offset-13{margin-left:54.1666666667%}.next-col-m-offset-14{margin-left:58.3333333333%}.next-col-m-offset-15{margin-left:62.5%}.next-col-m-offset-16{margin-left:66.6666666667%}.next-col-m-offset-17{margin-left:70.8333333333%}.next-col-m-offset-18{margin-left:75%}.next-col-m-offset-19{margin-left:79.1666666667%}.next-col-m-offset-20{margin-left:83.3333333333%}.next-col-m-offset-21{margin-left:87.5%}.next-col-m-offset-22{margin-left:91.6666666667%}.next-col-m-offset-23{margin-left:95.8333333333%}.next-col-m-offset-24{margin-left:100%}}@media(min-width:1200px){.next-col-l-offset-1{margin-left:4.1666666667%}.next-col-l-offset-2{margin-left:8.3333333333%}.next-col-l-offset-3{margin-left:12.5%}.next-col-l-offset-4{margin-left:16.6666666667%}.next-col-l-offset-5{margin-left:20.8333333333%}.next-col-l-offset-6{margin-left:25%}.next-col-l-offset-7{margin-left:29.1666666667%}.next-col-l-offset-8{margin-left:33.3333333333%}.next-col-l-offset-9{margin-left:37.5%}.next-col-l-offset-10{margin-left:41.6666666667%}.next-col-l-offset-11{margin-left:45.8333333333%}.next-col-l-offset-12{margin-left:50%}.next-col-l-offset-13{margin-left:54.1666666667%}.next-col-l-offset-14{margin-left:58.3333333333%}.next-col-l-offset-15{margin-left:62.5%}.next-col-l-offset-16{margin-left:66.6666666667%}.next-col-l-offset-17{margin-left:70.8333333333%}.next-col-l-offset-18{margin-left:75%}.next-col-l-offset-19{margin-left:79.1666666667%}.next-col-l-offset-20{margin-left:83.3333333333%}.next-col-l-offset-21{margin-left:87.5%}.next-col-l-offset-22{margin-left:91.6666666667%}.next-col-l-offset-23{margin-left:95.8333333333%}.next-col-l-offset-24{margin-left:100%}}@media(min-width:1500px){.next-col-xl-offset-1{margin-left:4.1666666667%}.next-col-xl-offset-2{margin-left:8.3333333333%}.next-col-xl-offset-3{margin-left:12.5%}.next-col-xl-offset-4{margin-left:16.6666666667%}.next-col-xl-offset-5{margin-left:20.8333333333%}.next-col-xl-offset-6{margin-left:25%}.next-col-xl-offset-7{margin-left:29.1666666667%}.next-col-xl-offset-8{margin-left:33.3333333333%}.next-col-xl-offset-9{margin-left:37.5%}.next-col-xl-offset-10{margin-left:41.6666666667%}.next-col-xl-offset-11{margin-left:45.8333333333%}.next-col-xl-offset-12{margin-left:50%}.next-col-xl-offset-13{margin-left:54.1666666667%}.next-col-xl-offset-14{margin-left:58.3333333333%}.next-col-xl-offset-15{margin-left:62.5%}.next-col-xl-offset-16{margin-left:66.6666666667%}.next-col-xl-offset-17{margin-left:70.8333333333%}.next-col-xl-offset-18{margin-left:75%}.next-col-xl-offset-19{margin-left:79.1666666667%}.next-col-xl-offset-20{margin-left:83.3333333333%}.next-col-xl-offset-21{margin-left:87.5%}.next-col-xl-offset-22{margin-left:91.6666666667%}.next-col-xl-offset-23{margin-left:95.8333333333%}.next-col-xl-offset-24{margin-left:100%}}.next-col-offset-fixed-1{margin-left:20px}.next-col-offset-fixed-2{margin-left:40px}.next-col-offset-fixed-3{margin-left:60px}.next-col-offset-fixed-4{margin-left:80px}.next-col-offset-fixed-5{margin-left:100px}.next-col-offset-fixed-6{margin-left:120px}.next-col-offset-fixed-7{margin-left:140px}.next-col-offset-fixed-8{margin-left:160px}.next-col-offset-fixed-9{margin-left:180px}.next-col-offset-fixed-10{margin-left:200px}.next-col-offset-fixed-11{margin-left:220px}.next-col-offset-fixed-12{margin-left:240px}.next-col-offset-fixed-13{margin-left:260px}.next-col-offset-fixed-14{margin-left:280px}.next-col-offset-fixed-15{margin-left:300px}.next-col-offset-fixed-16{margin-left:320px}.next-col-offset-fixed-17{margin-left:340px}.next-col-offset-fixed-18{margin-left:360px}.next-col-offset-fixed-19{margin-left:380px}.next-col-offset-fixed-20{margin-left:400px}.next-col-offset-fixed-21{margin-left:420px}.next-col-offset-fixed-22{margin-left:440px}.next-col-offset-fixed-23{margin-left:460px}.next-col-offset-fixed-24{margin-left:480px}.next-col-offset-fixed-25{margin-left:500px}.next-col-offset-fixed-26{margin-left:520px}.next-col-offset-fixed-27{margin-left:540px}.next-col-offset-fixed-28{margin-left:560px}.next-col-offset-fixed-29{margin-left:580px}.next-col-offset-fixed-30{margin-left:600px}.next-col-offset-fixed-xxs-1{margin-left:20px}.next-col-offset-fixed-xxs-2{margin-left:40px}.next-col-offset-fixed-xxs-3{margin-left:60px}.next-col-offset-fixed-xxs-4{margin-left:80px}.next-col-offset-fixed-xxs-5{margin-left:100px}.next-col-offset-fixed-xxs-6{margin-left:120px}.next-col-offset-fixed-xxs-7{margin-left:140px}.next-col-offset-fixed-xxs-8{margin-left:160px}.next-col-offset-fixed-xxs-9{margin-left:180px}.next-col-offset-fixed-xxs-10{margin-left:200px}.next-col-offset-fixed-xxs-11{margin-left:220px}.next-col-offset-fixed-xxs-12{margin-left:240px}.next-col-offset-fixed-xxs-13{margin-left:260px}.next-col-offset-fixed-xxs-14{margin-left:280px}.next-col-offset-fixed-xxs-15{margin-left:300px}.next-col-offset-fixed-xxs-16{margin-left:320px}.next-col-offset-fixed-xxs-17{margin-left:340px}.next-col-offset-fixed-xxs-18{margin-left:360px}.next-col-offset-fixed-xxs-19{margin-left:380px}.next-col-offset-fixed-xxs-20{margin-left:400px}.next-col-offset-fixed-xxs-21{margin-left:420px}.next-col-offset-fixed-xxs-22{margin-left:440px}.next-col-offset-fixed-xxs-23{margin-left:460px}.next-col-offset-fixed-xxs-24{margin-left:480px}.next-col-offset-fixed-xxs-25{margin-left:500px}.next-col-offset-fixed-xxs-26{margin-left:520px}.next-col-offset-fixed-xxs-27{margin-left:540px}.next-col-offset-fixed-xxs-28{margin-left:560px}.next-col-offset-fixed-xxs-29{margin-left:580px}.next-col-offset-fixed-xxs-30{margin-left:600px}.next-col-offset-fixed-xs-1{margin-left:20px}.next-col-offset-fixed-xs-2{margin-left:40px}.next-col-offset-fixed-xs-3{margin-left:60px}.next-col-offset-fixed-xs-4{margin-left:80px}.next-col-offset-fixed-xs-5{margin-left:100px}.next-col-offset-fixed-xs-6{margin-left:120px}.next-col-offset-fixed-xs-7{margin-left:140px}.next-col-offset-fixed-xs-8{margin-left:160px}.next-col-offset-fixed-xs-9{margin-left:180px}.next-col-offset-fixed-xs-10{margin-left:200px}.next-col-offset-fixed-xs-11{margin-left:220px}.next-col-offset-fixed-xs-12{margin-left:240px}.next-col-offset-fixed-xs-13{margin-left:260px}.next-col-offset-fixed-xs-14{margin-left:280px}.next-col-offset-fixed-xs-15{margin-left:300px}.next-col-offset-fixed-xs-16{margin-left:320px}.next-col-offset-fixed-xs-17{margin-left:340px}.next-col-offset-fixed-xs-18{margin-left:360px}.next-col-offset-fixed-xs-19{margin-left:380px}.next-col-offset-fixed-xs-20{margin-left:400px}.next-col-offset-fixed-xs-21{margin-left:420px}.next-col-offset-fixed-xs-22{margin-left:440px}.next-col-offset-fixed-xs-23{margin-left:460px}.next-col-offset-fixed-xs-24{margin-left:480px}.next-col-offset-fixed-xs-25{margin-left:500px}.next-col-offset-fixed-xs-26{margin-left:520px}.next-col-offset-fixed-xs-27{margin-left:540px}.next-col-offset-fixed-xs-28{margin-left:560px}.next-col-offset-fixed-xs-29{margin-left:580px}.next-col-offset-fixed-xs-30{margin-left:600px}.next-col-offset-fixed-s-1{margin-left:20px}.next-col-offset-fixed-s-2{margin-left:40px}.next-col-offset-fixed-s-3{margin-left:60px}.next-col-offset-fixed-s-4{margin-left:80px}.next-col-offset-fixed-s-5{margin-left:100px}.next-col-offset-fixed-s-6{margin-left:120px}.next-col-offset-fixed-s-7{margin-left:140px}.next-col-offset-fixed-s-8{margin-left:160px}.next-col-offset-fixed-s-9{margin-left:180px}.next-col-offset-fixed-s-10{margin-left:200px}.next-col-offset-fixed-s-11{margin-left:220px}.next-col-offset-fixed-s-12{margin-left:240px}.next-col-offset-fixed-s-13{margin-left:260px}.next-col-offset-fixed-s-14{margin-left:280px}.next-col-offset-fixed-s-15{margin-left:300px}.next-col-offset-fixed-s-16{margin-left:320px}.next-col-offset-fixed-s-17{margin-left:340px}.next-col-offset-fixed-s-18{margin-left:360px}.next-col-offset-fixed-s-19{margin-left:380px}.next-col-offset-fixed-s-20{margin-left:400px}.next-col-offset-fixed-s-21{margin-left:420px}.next-col-offset-fixed-s-22{margin-left:440px}.next-col-offset-fixed-s-23{margin-left:460px}.next-col-offset-fixed-s-24{margin-left:480px}.next-col-offset-fixed-s-25{margin-left:500px}.next-col-offset-fixed-s-26{margin-left:520px}.next-col-offset-fixed-s-27{margin-left:540px}.next-col-offset-fixed-s-28{margin-left:560px}.next-col-offset-fixed-s-29{margin-left:580px}.next-col-offset-fixed-s-30{margin-left:600px}.next-col-offset-fixed-m-1{margin-left:20px}.next-col-offset-fixed-m-2{margin-left:40px}.next-col-offset-fixed-m-3{margin-left:60px}.next-col-offset-fixed-m-4{margin-left:80px}.next-col-offset-fixed-m-5{margin-left:100px}.next-col-offset-fixed-m-6{margin-left:120px}.next-col-offset-fixed-m-7{margin-left:140px}.next-col-offset-fixed-m-8{margin-left:160px}.next-col-offset-fixed-m-9{margin-left:180px}.next-col-offset-fixed-m-10{margin-left:200px}.next-col-offset-fixed-m-11{margin-left:220px}.next-col-offset-fixed-m-12{margin-left:240px}.next-col-offset-fixed-m-13{margin-left:260px}.next-col-offset-fixed-m-14{margin-left:280px}.next-col-offset-fixed-m-15{margin-left:300px}.next-col-offset-fixed-m-16{margin-left:320px}.next-col-offset-fixed-m-17{margin-left:340px}.next-col-offset-fixed-m-18{margin-left:360px}.next-col-offset-fixed-m-19{margin-left:380px}.next-col-offset-fixed-m-20{margin-left:400px}.next-col-offset-fixed-m-21{margin-left:420px}.next-col-offset-fixed-m-22{margin-left:440px}.next-col-offset-fixed-m-23{margin-left:460px}.next-col-offset-fixed-m-24{margin-left:480px}.next-col-offset-fixed-m-25{margin-left:500px}.next-col-offset-fixed-m-26{margin-left:520px}.next-col-offset-fixed-m-27{margin-left:540px}.next-col-offset-fixed-m-28{margin-left:560px}.next-col-offset-fixed-m-29{margin-left:580px}.next-col-offset-fixed-m-30{margin-left:600px}.next-col-offset-fixed-l-1{margin-left:20px}.next-col-offset-fixed-l-2{margin-left:40px}.next-col-offset-fixed-l-3{margin-left:60px}.next-col-offset-fixed-l-4{margin-left:80px}.next-col-offset-fixed-l-5{margin-left:100px}.next-col-offset-fixed-l-6{margin-left:120px}.next-col-offset-fixed-l-7{margin-left:140px}.next-col-offset-fixed-l-8{margin-left:160px}.next-col-offset-fixed-l-9{margin-left:180px}.next-col-offset-fixed-l-10{margin-left:200px}.next-col-offset-fixed-l-11{margin-left:220px}.next-col-offset-fixed-l-12{margin-left:240px}.next-col-offset-fixed-l-13{margin-left:260px}.next-col-offset-fixed-l-14{margin-left:280px}.next-col-offset-fixed-l-15{margin-left:300px}.next-col-offset-fixed-l-16{margin-left:320px}.next-col-offset-fixed-l-17{margin-left:340px}.next-col-offset-fixed-l-18{margin-left:360px}.next-col-offset-fixed-l-19{margin-left:380px}.next-col-offset-fixed-l-20{margin-left:400px}.next-col-offset-fixed-l-21{margin-left:420px}.next-col-offset-fixed-l-22{margin-left:440px}.next-col-offset-fixed-l-23{margin-left:460px}.next-col-offset-fixed-l-24{margin-left:480px}.next-col-offset-fixed-l-25{margin-left:500px}.next-col-offset-fixed-l-26{margin-left:520px}.next-col-offset-fixed-l-27{margin-left:540px}.next-col-offset-fixed-l-28{margin-left:560px}.next-col-offset-fixed-l-29{margin-left:580px}.next-col-offset-fixed-l-30{margin-left:600px}.next-col-offset-fixed-xl-1{margin-left:20px}.next-col-offset-fixed-xl-2{margin-left:40px}.next-col-offset-fixed-xl-3{margin-left:60px}.next-col-offset-fixed-xl-4{margin-left:80px}.next-col-offset-fixed-xl-5{margin-left:100px}.next-col-offset-fixed-xl-6{margin-left:120px}.next-col-offset-fixed-xl-7{margin-left:140px}.next-col-offset-fixed-xl-8{margin-left:160px}.next-col-offset-fixed-xl-9{margin-left:180px}.next-col-offset-fixed-xl-10{margin-left:200px}.next-col-offset-fixed-xl-11{margin-left:220px}.next-col-offset-fixed-xl-12{margin-left:240px}.next-col-offset-fixed-xl-13{margin-left:260px}.next-col-offset-fixed-xl-14{margin-left:280px}.next-col-offset-fixed-xl-15{margin-left:300px}.next-col-offset-fixed-xl-16{margin-left:320px}.next-col-offset-fixed-xl-17{margin-left:340px}.next-col-offset-fixed-xl-18{margin-left:360px}.next-col-offset-fixed-xl-19{margin-left:380px}.next-col-offset-fixed-xl-20{margin-left:400px}.next-col-offset-fixed-xl-21{margin-left:420px}.next-col-offset-fixed-xl-22{margin-left:440px}.next-col-offset-fixed-xl-23{margin-left:460px}.next-col-offset-fixed-xl-24{margin-left:480px}.next-col-offset-fixed-xl-25{margin-left:500px}.next-col-offset-fixed-xl-26{margin-left:520px}.next-col-offset-fixed-xl-27{margin-left:540px}.next-col-offset-fixed-xl-28{margin-left:560px}.next-col-offset-fixed-xl-29{margin-left:580px}.next-col-offset-fixed-xl-30{margin-left:600px}.next-col.next-col-hidden{display:none}@media(min-width:320px)and (max-width:479px){.next-col.next-col-xxs-hidden{display:none}}@media(min-width:480px)and (max-width:719px){.next-col.next-col-xs-hidden{display:none}}@media(min-width:720px)and (max-width:989px){.next-col.next-col-s-hidden{display:none}}@media(min-width:990px)and (max-width:1199px){.next-col.next-col-m-hidden{display:none}}@media(min-width:1200px)and (max-width:1499px){.next-col.next-col-l-hidden{display:none}}@media(min-width:1500px){.next-col.next-col-xl-hidden{display:none}}.next-row.next-row-hidden{display:none}@media(min-width:320px)and (max-width:479px){.next-row.next-row-xxs-hidden{display:none}}@media(min-width:480px)and (max-width:719px){.next-row.next-row-xs-hidden{display:none}}@media(min-width:720px)and (max-width:989px){.next-row.next-row-s-hidden{display:none}}@media(min-width:990px)and (max-width:1199px){.next-row.next-row-m-hidden{display:none}}@media(min-width:1200px)and (max-width:1499px){.next-row.next-row-l-hidden{display:none}}@media(min-width:1500px){.next-row.next-row-xl-hidden{display:none}}.next-col-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}@media(min-width:320px){.next-col-xxs-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-xxs-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-xxs-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-xxs-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-xxs-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-xxs-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-xxs-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-xxs-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-xxs-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-xxs-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-xxs-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-xxs-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-xxs-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-xxs-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-xxs-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-xxs-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-xxs-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-xxs-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-xxs-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-xxs-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-xxs-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-xxs-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-xxs-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-xxs-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}}@media(min-width:480px){.next-col-xs-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-xs-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-xs-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-xs-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-xs-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-xs-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-xs-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-xs-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-xs-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-xs-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-xs-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-xs-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-xs-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-xs-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-xs-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-xs-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-xs-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-xs-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-xs-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-xs-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-xs-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-xs-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-xs-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-xs-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}}@media(min-width:720px){.next-col-s-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-s-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-s-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-s-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-s-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-s-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-s-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-s-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-s-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-s-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-s-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-s-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-s-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-s-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-s-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-s-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-s-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-s-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-s-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-s-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-s-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-s-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-s-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-s-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}}@media(min-width:990px){.next-col-m-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-m-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-m-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-m-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-m-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-m-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-m-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-m-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-m-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-m-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-m-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-m-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-m-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-m-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-m-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-m-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-m-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-m-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-m-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-m-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-m-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-m-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-m-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-m-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}}@media(min-width:1200px){.next-col-l-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-l-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-l-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-l-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-l-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-l-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-l-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-l-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-l-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-l-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-l-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-l-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-l-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-l-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-l-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-l-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-l-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-l-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-l-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-l-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-l-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-l-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-l-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-l-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}}@media(min-width:1500px){.next-col-xl-offset-1[dir=rtl]{margin-right:4.1666666667%;margin-left:auto}.next-col-xl-offset-2[dir=rtl]{margin-right:8.3333333333%;margin-left:auto}.next-col-xl-offset-3[dir=rtl]{margin-right:12.5%;margin-left:auto}.next-col-xl-offset-4[dir=rtl]{margin-right:16.6666666667%;margin-left:auto}.next-col-xl-offset-5[dir=rtl]{margin-right:20.8333333333%;margin-left:auto}.next-col-xl-offset-6[dir=rtl]{margin-right:25%;margin-left:auto}.next-col-xl-offset-7[dir=rtl]{margin-right:29.1666666667%;margin-left:auto}.next-col-xl-offset-8[dir=rtl]{margin-right:33.3333333333%;margin-left:auto}.next-col-xl-offset-9[dir=rtl]{margin-right:37.5%;margin-left:auto}.next-col-xl-offset-10[dir=rtl]{margin-right:41.6666666667%;margin-left:auto}.next-col-xl-offset-11[dir=rtl]{margin-right:45.8333333333%;margin-left:auto}.next-col-xl-offset-12[dir=rtl]{margin-right:50%;margin-left:auto}.next-col-xl-offset-13[dir=rtl]{margin-right:54.1666666667%;margin-left:auto}.next-col-xl-offset-14[dir=rtl]{margin-right:58.3333333333%;margin-left:auto}.next-col-xl-offset-15[dir=rtl]{margin-right:62.5%;margin-left:auto}.next-col-xl-offset-16[dir=rtl]{margin-right:66.6666666667%;margin-left:auto}.next-col-xl-offset-17[dir=rtl]{margin-right:70.8333333333%;margin-left:auto}.next-col-xl-offset-18[dir=rtl]{margin-right:75%;margin-left:auto}.next-col-xl-offset-19[dir=rtl]{margin-right:79.1666666667%;margin-left:auto}.next-col-xl-offset-20[dir=rtl]{margin-right:83.3333333333%;margin-left:auto}.next-col-xl-offset-21[dir=rtl]{margin-right:87.5%;margin-left:auto}.next-col-xl-offset-22[dir=rtl]{margin-right:91.6666666667%;margin-left:auto}.next-col-xl-offset-23[dir=rtl]{margin-right:95.8333333333%;margin-left:auto}.next-col-xl-offset-24[dir=rtl]{margin-right:100%;margin-left:auto}}.next-col-offset-fixed-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-col-offset-fixed-xxs-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-xxs-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-xxs-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-xxs-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-xxs-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-xxs-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-xxs-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-xxs-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-xxs-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-xxs-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-xxs-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-xxs-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-xxs-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-xxs-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-xxs-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-xxs-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-xxs-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-xxs-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-xxs-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-xxs-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-xxs-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-xxs-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-xxs-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-xxs-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-xxs-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-xxs-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-xxs-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-xxs-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-xxs-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-xxs-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-col-offset-fixed-xs-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-xs-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-xs-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-xs-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-xs-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-xs-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-xs-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-xs-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-xs-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-xs-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-xs-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-xs-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-xs-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-xs-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-xs-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-xs-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-xs-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-xs-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-xs-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-xs-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-xs-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-xs-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-xs-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-xs-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-xs-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-xs-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-xs-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-xs-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-xs-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-xs-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-col-offset-fixed-s-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-s-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-s-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-s-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-s-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-s-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-s-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-s-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-s-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-s-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-s-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-s-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-s-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-s-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-s-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-s-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-s-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-s-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-s-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-s-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-s-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-s-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-s-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-s-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-s-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-s-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-s-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-s-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-s-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-s-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-col-offset-fixed-m-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-m-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-m-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-m-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-m-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-m-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-m-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-m-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-m-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-m-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-m-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-m-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-m-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-m-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-m-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-m-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-m-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-m-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-m-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-m-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-m-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-m-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-m-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-m-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-m-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-m-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-m-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-m-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-m-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-m-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-col-offset-fixed-l-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-l-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-l-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-l-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-l-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-l-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-l-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-l-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-l-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-l-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-l-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-l-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-l-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-l-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-l-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-l-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-l-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-l-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-l-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-l-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-l-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-l-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-l-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-l-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-l-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-l-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-l-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-l-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-l-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-l-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-col-offset-fixed-xl-1[dir=rtl]{margin-right:20px;margin-left:auto}.next-col-offset-fixed-xl-2[dir=rtl]{margin-right:40px;margin-left:auto}.next-col-offset-fixed-xl-3[dir=rtl]{margin-right:60px;margin-left:auto}.next-col-offset-fixed-xl-4[dir=rtl]{margin-right:80px;margin-left:auto}.next-col-offset-fixed-xl-5[dir=rtl]{margin-right:100px;margin-left:auto}.next-col-offset-fixed-xl-6[dir=rtl]{margin-right:120px;margin-left:auto}.next-col-offset-fixed-xl-7[dir=rtl]{margin-right:140px;margin-left:auto}.next-col-offset-fixed-xl-8[dir=rtl]{margin-right:160px;margin-left:auto}.next-col-offset-fixed-xl-9[dir=rtl]{margin-right:180px;margin-left:auto}.next-col-offset-fixed-xl-10[dir=rtl]{margin-right:200px;margin-left:auto}.next-col-offset-fixed-xl-11[dir=rtl]{margin-right:220px;margin-left:auto}.next-col-offset-fixed-xl-12[dir=rtl]{margin-right:240px;margin-left:auto}.next-col-offset-fixed-xl-13[dir=rtl]{margin-right:260px;margin-left:auto}.next-col-offset-fixed-xl-14[dir=rtl]{margin-right:280px;margin-left:auto}.next-col-offset-fixed-xl-15[dir=rtl]{margin-right:300px;margin-left:auto}.next-col-offset-fixed-xl-16[dir=rtl]{margin-right:320px;margin-left:auto}.next-col-offset-fixed-xl-17[dir=rtl]{margin-right:340px;margin-left:auto}.next-col-offset-fixed-xl-18[dir=rtl]{margin-right:360px;margin-left:auto}.next-col-offset-fixed-xl-19[dir=rtl]{margin-right:380px;margin-left:auto}.next-col-offset-fixed-xl-20[dir=rtl]{margin-right:400px;margin-left:auto}.next-col-offset-fixed-xl-21[dir=rtl]{margin-right:420px;margin-left:auto}.next-col-offset-fixed-xl-22[dir=rtl]{margin-right:440px;margin-left:auto}.next-col-offset-fixed-xl-23[dir=rtl]{margin-right:460px;margin-left:auto}.next-col-offset-fixed-xl-24[dir=rtl]{margin-right:480px;margin-left:auto}.next-col-offset-fixed-xl-25[dir=rtl]{margin-right:500px;margin-left:auto}.next-col-offset-fixed-xl-26[dir=rtl]{margin-right:520px;margin-left:auto}.next-col-offset-fixed-xl-27[dir=rtl]{margin-right:540px;margin-left:auto}.next-col-offset-fixed-xl-28[dir=rtl]{margin-right:560px;margin-left:auto}.next-col-offset-fixed-xl-29[dir=rtl]{margin-right:580px;margin-left:auto}.next-col-offset-fixed-xl-30[dir=rtl]{margin-right:600px;margin-left:auto}.next-responsive-grid{box-sizing:border-box;display:grid}.next-responsive-grid *,.next-responsive-grid :after,.next-responsive-grid :before{box-sizing:border-box}.next-responsive-grid-ie{display:block}.next-form,.next-form *,.next-form :after,.next-form :before{box-sizing:border-box}.next-form-preview.next-form-item .next-form-item-label{color:#666}.next-form-preview.next-form-item .next-form-preview{color:#333}.next-form-preview.next-form-item.next-medium .next-form-item-label{font-size:14px;line-height:28px}.next-form-preview.next-form-item.next-small .next-form-item-label{font-size:12px;line-height:20px}.next-form-preview.next-form-item.next-large .next-form-item-label{font-size:16px;line-height:40px}.next-form-responsive-grid .next-form-item-control{flex:1}.next-form-responsive-grid .next-form-item{margin-bottom:0}.next-form-responsive-grid .next-form-item.next-left{display:flex}.next-form-responsive-grid.next-small .next-responsive-grid{gap:16px}.next-form-responsive-grid.next-small .next-form-item.next-left .next-form-item-label{line-height:1.4;margin-top:6px;margin-bottom:6px}.next-form-responsive-grid.next-medium .next-responsive-grid{gap:20px}.next-form-responsive-grid.next-medium .next-form-item.next-left .next-form-item-label{line-height:1.4;margin-top:9px;margin-bottom:9px}.next-form-responsive-grid.next-large .next-responsive-grid{gap:24px}.next-form-responsive-grid.next-large .next-form-item.next-left .next-form-item-label{line-height:1.4;margin-top:12px;margin-bottom:12px}.next-form-item{margin-bottom:16px}.next-form-item.has-error>.next-form-item-control>.next-form-item-help{color:#d23c26}.next-form-item.has-warning>.next-form-item-control>.next-form-item-help{color:#f1c826}.next-form-item .next-form-item-label,.next-form-item .next-form-text-align,.next-form-item p{line-height:32px}.next-form-item .next-form-text-align,.next-form-item p{margin:0}.next-form-item .next-checkbox-group,.next-form-item .next-checkbox-wrapper,.next-form-item .next-radio-group,.next-form-item .next-radio-wrapper,.next-form-item .next-rating{line-height:28px}.next-form-item .next-form-preview{font-size:14px;line-height:28px}.next-form-item .next-form-preview.next-input-textarea>p{font-size:14px;text-align:justify;min-height:19.6px;line-height:1.4;margin-top:4.2px}.next-form-item .next-form-item-label{font-size:14px}.next-form-item .next-form-item-label>label{display:inline-block;line-height:1.5}.next-form-item.next-large{margin-bottom:20px}.next-form-item.next-large .next-form-item-label,.next-form-item.next-large .next-form-text-align,.next-form-item.next-large p{line-height:40px}.next-form-item.next-large .next-checkbox-group,.next-form-item.next-large .next-checkbox-wrapper,.next-form-item.next-large .next-radio-group,.next-form-item.next-large .next-radio-wrapper,.next-form-item.next-large .next-rating{line-height:39px}.next-form-item.next-large .next-form-preview{font-size:16px;line-height:40px}.next-form-item.next-large .next-form-preview.next-input-textarea>p{font-size:16px;text-align:justify;min-height:22.4px;line-height:1.4;margin-top:8.8px}.next-form-item.next-large .next-switch{margin-top:7px}.next-form-item.next-large .next-form-item-label{font-size:16px}.next-form-item.next-small{margin-bottom:12px}.next-form-item.next-small .next-checkbox-group,.next-form-item.next-small .next-checkbox-wrapper,.next-form-item.next-small .next-form-item-label,.next-form-item.next-small .next-form-text-align,.next-form-item.next-small .next-radio-group,.next-form-item.next-small .next-radio-wrapper,.next-form-item.next-small .next-rating,.next-form-item.next-small p{line-height:24px}.next-form-item.next-small .next-form-preview{font-size:12px;line-height:20px}.next-form-item.next-small .next-form-preview.next-input-textarea>p{font-size:12px;text-align:justify;min-height:16.8px;line-height:1.4;margin-top:1.6px}.next-form-item.next-small .next-form-item-label{font-size:12px}.next-form-item.next-top>.next-form-item-label{margin-bottom:2px}.next-form-item.next-inset .next-form-item-label{padding-right:0;padding-left:0;line-height:inherit}.next-form-item-control .next-form-text-align{margin:0}.next-form-item-control>.next-input,.next-form-item-control>.next-input-group,.next-form-item-fullwidth .next-form-item-control>.next-date-picker,.next-form-item-fullwidth .next-form-item-control>.next-input,.next-form-item-fullwidth .next-form-item-control>.next-input-group,.next-form-item-fullwidth .next-form-item-control>.next-month-picker,.next-form-item-fullwidth .next-form-item-control>.next-range-picker,.next-form-item-fullwidth .next-form-item-control>.next-select,.next-form-item-fullwidth .next-form-item-control>.next-time-picker,.next-form-item-fullwidth .next-form-item-control>.next-year-picker{width:100%}.next-form-item-fullwidth .next-form-item-control>.next-date-picker2 .next-date-picker2-input input{width:inherit}.next-form-item-label{display:inline-block;vertical-align:top;color:#666;text-align:right;padding-right:12px}.next-form-item-label label[required]:before{margin-right:4px;content:"*";color:#d23c26}.next-form-item-label.has-colon label:after{content:":";position:relative;top:-.5px;margin:0 0 0 2px}.next-form-item-label.next-left{text-align:left}.next-form-item-label.next-left>label[required]:before{display:none}.next-form-item-label.next-left>label[required]:after{margin-left:4px;content:"*";color:#d23c26}.next-form-item-help{margin-top:4px;font-size:12px;line-height:1.5;color:#999}.next-form.next-inline .next-form-item{display:inline-block;vertical-align:top}.next-form.next-inline .next-form-item.next-left .next-form-item-control{display:inline-block;vertical-align:top;line-height:0}.next-form.next-inline .next-form-item:not(:last-child){margin-right:20px}.next-form.next-inline .next-form-item.next-large:not(:last-child){margin-right:24px}.next-form.next-inline .next-form-item.next-small:not(:last-child){margin-right:16px}@media screen and (min-width:0\0)and (min-resolution:0.001dpcm){.next-form-item.next-left>.next-form-item-label,.next-form.next-inline .next-form-item.next-left .next-form-item-control{display:table-cell}}.next-form[dir=rtl] .next-form-item-label{text-align:left;padding-left:12px;padding-right:0}.next-form[dir=rtl].next-inline .next-form-item:not(:last-child){margin-left:20px;margin-right:0}.next-form[dir=rtl].next-inline .next-form-item.next-large:not(:last-child){margin-left:24px;margin-right:0}.next-form[dir=rtl].next-inline .next-form-item.next-small:not(:last-child){margin-left:16px;margin-right:0}.next-avatar{position:relative;display:inline-block;overflow:hidden;color:#fff;white-space:nowrap;text-align:center;vertical-align:middle;background:#f2f2f2;border:0 solid #fff;box-shadow:none;width:40px;height:40px;line-height:40px;border-radius:50%}.next-avatar-image{background:transparent}.next-avatar-string{position:absolute;left:50%;transform-origin:0 center}.next-avatar-large{width:52px;height:52px;line-height:52px;border-radius:50%}.next-avatar-large-string{position:absolute;left:50%;transform-origin:0 center}.next-avatar-small{width:28px;height:28px;line-height:28px;border-radius:50%}.next-avatar-small-string{position:absolute;left:50%;transform-origin:0 center}.next-avatar-square{border-radius:3px}.next-avatar>img{display:block;width:100%;height:100%;object-fit:cover}.next-select{display:inline-block;position:relative;font-size:0;vertical-align:middle}.next-select,.next-select *,.next-select :after,.next-select :before{box-sizing:border-box}.next-select-trigger{min-width:100px;outline:0;transition:all .1s linear}.next-select-trigger .next-input-label{flex:0 0 auto;width:auto}.next-select-trigger .next-select-values{display:block;width:100%;flex:1 1 0;overflow:hidden}.next-select-trigger .next-select-values>em{font-style:inherit}.next-select-trigger .next-select-values input{padding-left:0;padding-right:0}.next-select-trigger .next-input-control{flex:0 0 auto;width:auto}.next-select-trigger .next-input-control>*{display:inline-block;width:auto}.next-select-trigger .next-input-control>.next-select-arrow{padding-right:0}.next-select-trigger .next-input.next-disabled em{color:#ccc}.next-select-trigger .next-input.next-disabled .next-select-arrow{cursor:not-allowed}.next-select-trigger .next-select-clear{display:none}.next-select-trigger.next-has-clear:hover .next-select-clear{display:inline-block}.next-select-trigger.next-has-clear:hover .next-select-arrow{display:none}.next-select .next-select-inner{display:inline-flex;align-items:center;width:100%;min-width:100px;outline:0;color:#333}.next-select .next-select-inner .next-tag{line-height:1;margin-right:4px;margin-bottom:3px;padding-left:0;padding-right:0}.next-select .next-select-inner .next-input-inner{width:auto}.next-select-trigger-search{position:relative;display:inline-block;vertical-align:top;overflow:hidden;width:100%;max-width:100%}.next-select-trigger-search>input,.next-select-trigger-search>span{display:block;font-size:inherit;font-family:inherit;letter-spacing:inherit;white-space:nowrap;overflow:hidden}.next-select-trigger-search input{position:absolute;background-color:transparent;width:100%;height:100%!important;z-index:1;left:0;border:0;outline:0;margin:0;padding:0;cursor:inherit}.next-select-trigger-search>span{position:relative;visibility:hidden;white-space:pre;max-width:100%;z-index:-1}.next-select-single.next-no-search{cursor:pointer}.next-select-single.next-has-search.next-active .next-select-values>em{display:none}.next-select-single.next-inactive .next-select-values>em+.next-select-trigger-search,.next-select-single.next-no-search .next-select-values>em+.next-select-trigger-search{width:1px;opacity:0;filter:alpha(opacity=0)}.next-select-single .next-select-values{display:inline-flex;align-items:center}.next-select-single .next-select-values>em{vertical-align:middle;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.next-select-multiple .next-select-compact{position:relative;white-space:nowrap}.next-select-multiple .next-select-compact .next-select-trigger-search{width:auto}.next-select-multiple .next-select-compact .next-select-tag-compact{position:absolute;top:0;right:0;z-index:1;padding:0 4px 0 16px;color:#333;background:linear-gradient(90deg,transparent,#fff 10px)}.next-select-multiple .next-disabled .next-select-tag-compact{background:linear-gradient(90deg,transparent,#fafafa 10px)}.next-select-multiple .next-select-values,.next-select-tag .next-select-values{margin-bottom:-3px;height:auto!important}.next-select-multiple .next-select-trigger-search,.next-select-tag .next-select-trigger-search{margin-bottom:3px}.next-select-multiple .next-tag+.next-select-trigger-search,.next-select-tag .next-tag+.next-select-trigger-search{width:auto;min-width:1px}.next-select-multiple .next-input,.next-select-tag .next-input{height:auto;align-items:start}.next-select-multiple.next-small .next-select-values,.next-select-tag.next-small .next-select-values{min-height:22px;padding-top:4px;padding-bottom:4px;line-height:14px}.next-select-multiple.next-small .next-select-values-compact,.next-select-tag.next-small .next-select-values-compact{height:24px!important}.next-select-multiple.next-small .next-tag,.next-select-tag.next-small .next-tag{border:0;padding-top:0;padding-bottom:0;height:14px}.next-select-multiple.next-small .next-tag-body,.next-select-multiple.next-small .next-tag .next-tag-body,.next-select-multiple.next-small .next-tag .next-tag-close-btn,.next-select-tag.next-small .next-tag-body,.next-select-tag.next-small .next-tag .next-tag-body,.next-select-tag.next-small .next-tag .next-tag-close-btn{line-height:14px}.next-select-multiple.next-small .next-input-control,.next-select-multiple.next-small .next-input-inner,.next-select-multiple.next-small .next-input-label,.next-select-multiple.next-small .next-select-tag-compact,.next-select-tag.next-small .next-input-control,.next-select-tag.next-small .next-input-inner,.next-select-tag.next-small .next-input-label,.next-select-tag.next-small .next-select-tag-compact{line-height:22px}.next-select-multiple.next-medium .next-select-values,.next-select-tag.next-medium .next-select-values{min-height:30px;padding-top:5px;padding-bottom:5px;line-height:20px}.next-select-multiple.next-medium .next-select-values-compact,.next-select-tag.next-medium .next-select-values-compact{height:32px!important}.next-select-multiple.next-medium .next-tag,.next-select-tag.next-medium .next-tag{padding-top:1px;padding-bottom:1px;height:20px}.next-select-multiple.next-medium .next-tag .next-tag-body,.next-select-multiple.next-medium .next-tag .next-tag-close-btn,.next-select-tag.next-medium .next-tag .next-tag-body,.next-select-tag.next-medium .next-tag .next-tag-close-btn{line-height:18px}.next-select-multiple.next-medium .next-input-control,.next-select-multiple.next-medium .next-input-inner,.next-select-multiple.next-medium .next-input-label,.next-select-multiple.next-medium .next-select-tag-compact,.next-select-tag.next-medium .next-input-control,.next-select-tag.next-medium .next-input-inner,.next-select-tag.next-medium .next-input-label,.next-select-tag.next-medium .next-select-tag-compact{line-height:30px}.next-select-multiple.next-large .next-select-values,.next-select-tag.next-large .next-select-values{min-height:38px;padding-top:7px;padding-bottom:7px;line-height:24px}.next-select-multiple.next-large .next-select-values-compact,.next-select-tag.next-large .next-select-values-compact{height:40px!important}.next-select-multiple.next-large .next-tag,.next-select-tag.next-large .next-tag{padding-top:3px;padding-bottom:3px;height:24px}.next-select-multiple.next-large .next-tag .next-tag-body,.next-select-multiple.next-large .next-tag .next-tag-close-btn,.next-select-tag.next-large .next-tag .next-tag-body,.next-select-tag.next-large .next-tag .next-tag-close-btn{line-height:18px}.next-select-multiple.next-large .next-input-control,.next-select-multiple.next-large .next-input-inner,.next-select-multiple.next-large .next-input-label,.next-select-multiple.next-large .next-select-tag-compact,.next-select-tag.next-large .next-input-control,.next-select-tag.next-large .next-input-inner,.next-select-tag.next-large .next-input-label,.next-select-tag.next-large .next-select-tag-compact{line-height:38px}.next-select-auto-complete{width:160px}.next-select-auto-complete .next-input{width:100%}.next-select-auto-complete .next-input .next-input-hint-wrap{padding-right:1px}.next-select-auto-complete .next-input .next-select-arrow{padding-left:0}.next-select.next-active .next-select-arrow .next-icon-arrow-down{transform:rotate(180deg)}.next-select .next-select-unfold-icon:before{content:""}.next-select-symbol-fold:before{content:""}.next-select-arrow{cursor:pointer;width:auto!important;text-align:center;transition:all .1s linear}.next-select-popup-wrap{animation-duration:.3s;animation-timing-function:ease;padding:0}.next-select-spacing-tb{padding:0}.next-select-menu-wrapper{max-height:260px;overflow:auto;border:1px solid #e6e6e6;border-radius:3px;box-shadow:none}.next-select-menu-wrapper .next-select-menu{max-height:none;border:none}.next-select-menu{max-height:260px;overflow:auto}.next-select-menu .next-select-menu-empty-content{padding-left:8px;padding-right:8px;color:#999}.next-select-menu.next-select-auto-complete-menu.next-select-menu-empty{display:none}.next-select-menu .next-menu-item-text .next-icon{vertical-align:middle}.next-select-all{display:block;cursor:pointer;padding:0 8px;margin:0 12px 8px;border-bottom:1px solid #e6e6e6}.next-select-all:hover{color:#2580e7}.next-select-all .next-menu-icon-selected.next-icon{display:inline-block!important;top:auto;color:#209bfa}.next-select-highlight{color:#209bfa;font-size:14px}.next-select-in-ie.next-select-trigger .next-select-values{overflow:visible}.next-select-in-ie.next-select-trigger .next-input-control,.next-select-in-ie.next-select-trigger .next-input-label{width:1px}.next-select-in-ie.next-select-trigger .next-input-control>*{display:table-cell;width:1%}.next-select-in-ie.next-select-trigger .next-select-arrow{display:table-cell}.next-select-in-ie.next-select-trigger .next-select-clear{display:none}.next-select-in-ie.next-select-trigger.next-select-multiple .next-select-inner,.next-select-in-ie.next-select-trigger.next-select-tag .next-select-inner{vertical-align:top}.next-select-in-ie.next-select-trigger .next-select-inner,.next-select-in-ie.next-select-trigger.next-select-single .next-select-values{display:inline-table}.next-select-in-ie.next-select-trigger.next-select-single .next-input.next-small .next-select-values{line-height:24px}.next-select-in-ie.next-select-trigger.next-select-single .next-input.next-medium .next-select-values{line-height:32px}.next-select-in-ie.next-select-trigger.next-select-single .next-input.next-large .next-select-values{line-height:40px}.next-select-in-ie.next-select-trigger .next-select-trigger-search>span{max-width:100px}.next-select-in-ie.next-select-trigger.next-select-single.next-select-in-ie-fixwidth .next-select-values{position:relative}.next-select-in-ie.next-select-trigger.next-select-single.next-select-in-ie-fixwidth .next-select-values>em{position:absolute;display:inline-block;height:100%;line-height:1;vertical-align:middle;overflow:hidden;left:4px;right:0;top:30%}.next-select-in-ie.next-select-trigger.next-select-single.next-inactive .next-select-values>em+.next-select-trigger-search,.next-select-in-ie.next-select-trigger.next-select-single.next-no-search .next-select-values>em+.next-select-trigger-search{filter:alpha(opacity=0);font-size:0}.next-select-in-ie.next-select-trigger.next-no-search .next-select-trigger-search input{color:inherit}@media screen and (-webkit-min-device-pixel-ratio:0){.next-select-multiple .next-select-compact .next-select-tag-compact{background:linear-gradient(90deg,hsla(0,0%,100%,0),#fff 10px)}.next-select-multiple .next-disabled .next-select-tag-compact{background:linear-gradient(90deg,hsla(0,0%,100%,0),#fafafa 10px)}}.next-select.next-select-multiple[dir=rtl] .next-select-compact .next-select-tag-compact{left:0;right:auto;padding:0 16px 0 4px;background:linear-gradient(270deg,hsla(0,0%,100%,0),#fff 10px)}.next-list-header{border-bottom:1px solid #e6e6e6;color:#333}.next-list-footer{border-top:1px solid #e6e6e6;color:#666}.next-list-loading.next-loading{display:block}.next-list-empty{font-size:14px;color:#ccc;padding:32px 0;text-align:center}.next-list-items{margin:0;padding:0;list-style:none}.next-list-item{display:table;display:flex;width:100%;color:#666}.next-list-item-extra,.next-list-item-media{display:table-cell;display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;min-width:1px;flex-shrink:0;vertical-align:top}.next-list-item-extra{color:#999}.next-list-item-content{display:table-cell;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;flex:1;width:100%;vertical-align:middle}.next-list-item-title{color:#333}.next-list-medium .next-list-header{padding:16px 0;font-size:20px;font-weight:700}.next-list-medium .next-list-footer{padding:16px 0}.next-list-medium .next-list-item-media{padding-right:8px}.next-list-medium .next-list-item-extra{padding-left:8px}.next-list-medium .next-list-item{font-size:14px;line-height:1.5;padding:16px 0}.next-list-medium .next-list-item-title{font-weight:400;font-size:16px;line-height:1.5}.next-list-small .next-list-header{padding:8px 0;font-size:16px;font-weight:700}.next-list-small .next-list-footer{padding:8px 0}.next-list-small .next-list-item-media{padding-right:8px}.next-list-small .next-list-item-extra{padding-left:8px}.next-list-small .next-list-item{font-size:14px;font-weight:400;line-height:1.3;padding:8px 0}.next-list-small .next-list-item-title{font-size:14px;line-height:1.5}.next-list-divider .next-list-item{border-bottom:1px solid #e6e6e6}.next-list-divider .next-list-item:last-child{border-bottom:none}.next-list[dir=rtl] .next-list-item-media{padding-left:8px;padding-right:0}.next-list[dir=rtl] .next-list-item-extra{padding-right:8px;padding-left:0}.next-list[dir=rtl] .next-list-small .next-list-item-media{padding-left:8px;padding-right:0}.next-list[dir=rtl] .next-list-small .next-list-item-extra{padding-right:8px;padding-left:0}.next-menu-btn{display:inline-block;box-shadow:none}.next-menu-btn-spacing-tb{padding:0}.next-menu-btn .next-icon{transition:transform .1s linear}.next-menu-btn .next-menu-btn-arrow:before{content:""}.next-menu-btn.next-expand .next-menu-btn-arrow{transform:rotate(180deg)}.next-menu-btn-symbol-unfold:before{content:""}.next-menu-btn.next-btn-normal .next-menu-btn-arrow{color:#999}.next-menu-btn.next-btn-normal:hover .next-menu-btn-arrow{color:#333}.next-menu-btn.next-btn-secondary .next-menu-btn-arrow{color:#209bfa}.next-menu-btn.next-btn-secondary:hover .next-menu-btn-arrow{color:#fff}.next-menu-btn.next-btn-secondary.next-btn-text:hover .next-menu-btn-arrow{color:#209bfa}.next-menu-btn.next-btn-primary .next-menu-btn-arrow,.next-menu-btn.next-btn-primary:hover .next-menu-btn-arrow{color:#fff}.next-menu-btn.next-btn-text.next-btn-normal .next-menu-btn-arrow{color:#333}.next-menu-btn.next-btn-text.next-btn-normal:hover .next-menu-btn-arrow{color:#209bfa}.next-menu-btn.next-btn-text.next-btn-primary .next-menu-btn-arrow{color:#298dff}.next-menu-btn.next-btn-text.next-btn-primary:hover .next-menu-btn-arrow{color:#1274e7}.next-menu-btn.next-btn-ghost.next-btn-light .next-menu-btn-arrow{color:#333}.next-menu-btn.next-btn-ghost.next-btn-light:hover .next-menu-btn-arrow{color:#999}.next-menu-btn.next-btn-ghost.next-btn-dark .next-menu-btn-arrow,.next-menu-btn.next-btn-ghost.next-btn-dark:hover .next-menu-btn-arrow{color:#fff}.next-menu-btn.disabled .next-menu-btn-arrow,.next-menu-btn.next-btn-text.disabled .next-menu-btn-arrow,.next-menu-btn.next-btn-text[disabled] .next-menu-btn-arrow,.next-menu-btn[disabled] .next-menu-btn-arrow{color:#ccc}.next-menu-btn[disabled].next-btn-ghost.next-btn-dark .next-menu-btn-arrow{color:hsla(0,0%,100%,.4)}.next-menu-btn[disabled].next-btn-ghost.next-btn-light .next-menu-btn-arrow{color:rgba(0,0,0,.1)}.next-nav{min-width:auto;border-radius:0}.next-nav,.next-nav *,.next-nav :after,.next-nav :before{box-sizing:border-box}.next-nav-icon.next-icon{margin-right:12px;font-weight:inherit}.next-nav-icon.next-icon .next-icon-remote,.next-nav-icon.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav-group-label{height:40px;line-height:40px;font-size:14px}.next-nav-item .next-menu-item-text>span,.next-nav-item .next-nav-group-label>span{opacity:1;transition:opacity .1s linear}.next-nav-item .next-menu-item-text>a{text-decoration:none;color:inherit}.next-nav-item.next-focused .next-menu-hoz-icon-arrow.next-icon,.next-nav-item.next-focused .next-menu-icon-arrow.next-icon,.next-nav-item .next-menu-hoz-icon-arrow.next-icon,.next-nav-item .next-menu-icon-arrow.next-icon,.next-nav-item.next-opened .next-menu-hoz-icon-arrow.next-icon,.next-nav-item.next-opened .next-menu-icon-arrow.next-icon,.next-nav-item.next-selected .next-menu-hoz-icon-arrow.next-icon,.next-nav-item.next-selected .next-menu-icon-arrow.next-icon,.next-nav-item:hover .next-menu-hoz-icon-arrow.next-icon,.next-nav-item:hover .next-menu-icon-arrow.next-icon{color:inherit;top:0;transform-origin:center 50%}.next-nav.next-active .next-nav-item:before{position:absolute;transition:all .3s ease;content:""}.next-nav.next-hoz{padding:0;height:44px;line-height:42px;font-size:14px}.next-nav.next-hoz .next-menu-item.next-nav-item{margin-left:0;margin-right:0;padding:0 20px;border-radius:0}.next-nav.next-hoz .next-menu-item,.next-nav.next-hoz .next-menu-sub-menu-wrapper>.next-menu-item{margin-top:0;margin-bottom:0}.next-nav.next-hoz .next-menu-item-inner{height:42px;font-size:14px}.next-nav.next-hoz .next-menu-item.next-nav-item.next-nav-with-title{line-height:1;padding:12px 8px}.next-nav.next-hoz .next-menu-item.next-nav-item.next-nav-with-title .next-menu-item-inner{height:auto;min-height:42px}.next-nav.next-hoz .next-menu-item.next-nav-item.next-nav-with-title .next-nav-text{display:block;line-height:1;margin-top:8px;overflow:hidden;text-overflow:ellipsis}.next-nav.next-hoz .next-nav-group-label .next-menu-item-inner{height:40px;line-height:40px;font-size:14px}.next-nav.next-hoz .next-menu-header{float:left;height:42px}.next-nav.next-hoz .next-menu-footer{float:right;height:42px}.next-nav.next-hoz .next-nav-item:before{width:0;left:50%;height:2px}.next-nav.next-hoz .next-nav-item:hover:before{height:0}.next-nav.next-hoz.next-top .next-nav-item:before{top:-1px}.next-nav.next-hoz.next-bottom .next-nav-item:before{bottom:-1px}.next-nav.next-hoz .next-selected.next-nav-item:before{width:100%;left:0;height:2px}.next-nav.next-ver{padding:0;transition:width .3s ease;line-height:52px;font-size:14px}.next-nav.next-ver .next-menu-item.next-nav-item{margin-left:0;margin-right:0;padding:0 16px;border-radius:0}.next-nav.next-ver .next-menu-item:not(:first-child),.next-nav.next-ver .next-menu-sub-menu-wrapper:not(:first-child)>.next-menu-item{margin-top:0}.next-nav.next-ver .next-menu-item:not(:last-child),.next-nav.next-ver .next-menu-sub-menu-wrapper:not(:last-child)>.next-menu-item{margin-bottom:0}.next-nav.next-ver .next-menu-item-inner{height:52px;font-size:14px}.next-nav.next-ver .next-menu-item.next-nav-item.next-nav-with-title{line-height:1;padding:12px 8px}.next-nav.next-ver .next-menu-item.next-nav-item.next-nav-with-title .next-menu-item-inner{height:auto;min-height:52px}.next-nav.next-ver .next-menu-item.next-nav-item.next-nav-with-title .next-nav-text{display:block;line-height:1;margin-top:8px;overflow:hidden;text-overflow:ellipsis}.next-nav.next-ver .next-nav-group-label .next-menu-item-inner{height:40px;line-height:40px;font-size:14px}.next-nav.next-ver>.next-menu-item:first-child,.next-nav.next-ver>.next-menu-sub-menu-wrapper:first-child>.next-menu-item{margin-top:0}.next-nav.next-ver>.next-menu-item:last-child,.next-nav.next-ver>.next-menu-sub-menu-wrapper:last-child>.next-menu-item{margin-bottom:0}.next-nav.next-ver .next-menu-sub-menu{line-height:52px}.next-nav.next-ver .next-menu-sub-menu .next-menu-item-inner{height:52px;font-size:14px}.next-nav.next-ver .next-nav-item:before{height:0;top:50%;width:2px}.next-nav.next-ver .next-nav-item:hover:before{width:0}.next-nav.next-ver.next-left .next-nav-item:before,.next-nav.next-ver.next-top .next-nav-item:before{left:-1px}.next-nav.next-ver.next-bottom .next-nav-item:before,.next-nav.next-ver.next-right .next-nav-item:before{right:-1px}.next-nav.next-ver .next-selected.next-nav-item:before{height:100%;top:0;width:2px}.next-nav.next-primary{border-width:0;background:#222;border-color:#222;color:#ddd;font-weight:400;box-shadow:4px 4px 8px 0 rgba(0,0,0,.12)}.next-nav.next-primary.next-hoz{line-height:44px}.next-nav.next-primary.next-hoz .next-menu-footer,.next-nav.next-primary.next-hoz .next-menu-header,.next-nav.next-primary.next-hoz .next-menu-item-inner{line-height:44px;height:44px}.next-nav.next-primary.next-hoz.next-top .next-nav-item:before{top:0}.next-nav.next-primary.next-hoz.next-bottom .next-nav-item:before{bottom:0}.next-nav.next-primary.next-ver.next-left .next-nav-item:before{left:0}.next-nav.next-primary.next-ver.next-right .next-nav-item:before{right:0}.next-nav.next-primary .next-nav-item.next-menu-item{background:#222;color:#ddd}.next-nav.next-primary .next-nav-item.next-menu-item.next-focused,.next-nav.next-primary .next-nav-item.next-menu-item:hover{background:#333;color:#fff;font-weight:400}.next-nav.next-primary .next-nav-item.next-menu-item.next-selected{background:#333;color:#fff;font-weight:700}.next-nav.next-primary .next-nav-item.next-menu-item.next-selected.next-nav-item{background:#333;color:#fff}.next-nav.next-primary .next-nav-item.next-menu-item.next-opened{background:#222;color:#fff}.next-nav.next-primary .next-nav-item.next-menu-item.next-child-selected{font-weight:700;background:transparent;color:#fff}.next-nav.next-primary .next-nav-item.next-menu-item.next-child-selected.next-nav-popup,.next-nav.next-primary .next-nav-item.next-menu-item.next-opened.next-nav-popup{color:#fff}.next-nav.next-primary .next-nav-item.next-menu-item:before,.next-nav.next-primary .next-nav-item.next-menu-item:hover:before{background:#209bfa}.next-nav.next-primary .next-menu-sub-menu .next-menu-item.next-opened{background:#222;color:#fff}.next-nav.next-primary .next-nav-group-label{color:#999;font-weight:400}.next-nav.next-primary .next-menu-sub-menu .next-menu-item{background:#151515;color:#ddd;font-weight:400}.next-nav.next-primary .next-menu-sub-menu .next-menu-item.next-focused,.next-nav.next-primary .next-menu-sub-menu .next-menu-item:hover{background:#333;color:#ddd}.next-nav.next-primary .next-menu-sub-menu .next-menu-item.next-selected,.next-nav.next-primary .next-menu-sub-menu .next-menu-item.next-selected.next-nav-item{background:#333;color:#fff}.next-nav.next-primary .next-nav-item.next-menu-item.next-disabled,.next-nav.next-primary .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a{color:#ccc;cursor:not-allowed}.next-nav.next-primary .next-nav-item.next-menu-item.next-disabled .next-menu-icon-arrow,.next-nav.next-primary .next-nav-item.next-menu-item.next-disabled .next-menu-icon-selected,.next-nav.next-primary .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-arrow,.next-nav.next-primary .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-selected{color:#ccc}.next-nav.next-secondary{border-width:0;background:#209bfa;border-color:#209bfa;color:#fff;font-weight:400;box-shadow:4px 4px 8px 0 rgba(0,0,0,.12)}.next-nav.next-secondary.next-hoz{line-height:44px}.next-nav.next-secondary.next-hoz .next-menu-footer,.next-nav.next-secondary.next-hoz .next-menu-header,.next-nav.next-secondary.next-hoz .next-menu-item-inner{line-height:44px;height:44px}.next-nav.next-secondary.next-hoz.next-top .next-nav-item:before{top:0}.next-nav.next-secondary.next-hoz.next-bottom .next-nav-item:before{bottom:0}.next-nav.next-secondary.next-ver.next-left .next-nav-item:before{left:0}.next-nav.next-secondary.next-ver.next-right .next-nav-item:before{right:0}.next-nav.next-secondary .next-nav-item.next-menu-item{background:#209bfa;color:#fff}.next-nav.next-secondary .next-nav-item.next-menu-item.next-focused,.next-nav.next-secondary .next-nav-item.next-menu-item:hover{background:#1274e7;color:#fff;font-weight:400}.next-nav.next-secondary .next-nav-item.next-menu-item.next-selected{background:#1274e7;color:#fff;font-weight:700}.next-nav.next-secondary .next-nav-item.next-menu-item.next-selected.next-nav-item{background:#1274e7;color:#fff}.next-nav.next-secondary .next-nav-item.next-menu-item.next-opened{background:transparent;color:#fff}.next-nav.next-secondary .next-nav-item.next-menu-item.next-child-selected{font-weight:700;background:transparent;color:#fff}.next-nav.next-secondary .next-nav-item.next-menu-item.next-child-selected.next-nav-popup,.next-nav.next-secondary .next-nav-item.next-menu-item.next-opened.next-nav-popup{color:#fff}.next-nav.next-secondary .next-nav-item.next-menu-item:before,.next-nav.next-secondary .next-nav-item.next-menu-item:hover:before{background:#1274e7}.next-nav.next-secondary .next-menu-sub-menu .next-menu-item.next-opened{background:transparent;color:#fff}.next-nav.next-secondary .next-nav-group-label{color:#fff;font-weight:400}.next-nav.next-secondary .next-menu-sub-menu .next-menu-item{background:#209bfa;color:#fff;font-weight:400}.next-nav.next-secondary .next-menu-sub-menu .next-menu-item.next-focused,.next-nav.next-secondary .next-menu-sub-menu .next-menu-item.next-selected,.next-nav.next-secondary .next-menu-sub-menu .next-menu-item.next-selected.next-nav-item,.next-nav.next-secondary .next-menu-sub-menu .next-menu-item:hover{background:#1274e7;color:#fff}.next-nav.next-secondary .next-nav-item.next-menu-item.next-disabled,.next-nav.next-secondary .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a{color:#add9ff;cursor:not-allowed}.next-nav.next-secondary .next-nav-item.next-menu-item.next-disabled .next-menu-icon-arrow,.next-nav.next-secondary .next-nav-item.next-menu-item.next-disabled .next-menu-icon-selected,.next-nav.next-secondary .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-arrow,.next-nav.next-secondary .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-selected{color:#add9ff}.next-nav.next-normal{border-color:#eee;font-weight:400;box-shadow:4px 4px 8px 0 rgba(0,0,0,.12)}.next-nav.next-normal,.next-nav.next-normal .next-nav-item.next-menu-item{background:#fff;color:#666}.next-nav.next-normal .next-nav-item.next-menu-item.next-focused,.next-nav.next-normal .next-nav-item.next-menu-item:hover{background:#fff;color:#333;font-weight:500}.next-nav.next-normal .next-nav-item.next-menu-item.next-selected{background:#e4f3fe;color:#209bfa;font-weight:700}.next-nav.next-normal .next-nav-item.next-menu-item.next-selected.next-nav-item{background:#e4f3fe;color:#209bfa}.next-nav.next-normal .next-nav-item.next-menu-item.next-opened{background:transparent;color:#333}.next-nav.next-normal .next-nav-item.next-menu-item.next-child-selected{font-weight:400;background:transparent;color:#209bfa}.next-nav.next-normal .next-nav-item.next-menu-item.next-opened.next-nav-popup{color:#333}.next-nav.next-normal .next-nav-item.next-menu-item.next-child-selected.next-nav-popup{color:#209bfa}.next-nav.next-normal .next-nav-item.next-menu-item:before{background:#209bfa}.next-nav.next-normal .next-nav-item.next-menu-item:hover:before{background:#1b84e0}.next-nav.next-normal .next-menu-sub-menu .next-menu-item.next-opened{background:transparent;color:#333}.next-nav.next-normal .next-nav-group-label{color:#999;font-weight:400}.next-nav.next-normal .next-menu-sub-menu .next-menu-item{background:#fafafa;color:#666;font-weight:400}.next-nav.next-normal .next-menu-sub-menu .next-menu-item.next-focused,.next-nav.next-normal .next-menu-sub-menu .next-menu-item:hover{background:#f9f9f9;color:#298dff}.next-nav.next-normal .next-menu-sub-menu .next-menu-item.next-selected,.next-nav.next-normal .next-menu-sub-menu .next-menu-item.next-selected.next-nav-item{background:#e4f3fe;color:#209bfa}.next-nav.next-normal .next-nav-item.next-menu-item.next-disabled,.next-nav.next-normal .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a{color:#999;cursor:not-allowed}.next-nav.next-normal .next-nav-item.next-menu-item.next-disabled .next-menu-icon-arrow,.next-nav.next-normal .next-nav-item.next-menu-item.next-disabled .next-menu-icon-selected,.next-nav.next-normal .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-arrow,.next-nav.next-normal .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-selected{color:#999}.next-nav.next-line{background:transparent;border-color:#e6e6e6;color:#333;font-weight:400;box-shadow:none}.next-nav.next-line.next-hoz{border-right-color:transparent}.next-nav.next-line.next-hoz,.next-nav.next-line.next-ver{border-top-color:transparent;border-left-color:transparent}.next-nav.next-line.next-ver{border-bottom-color:transparent}.next-nav.next-line .next-nav-item.next-menu-item{background:transparent;color:#333}.next-nav.next-line .next-nav-item.next-menu-item.next-focused,.next-nav.next-line .next-nav-item.next-menu-item:hover{background:transparent;color:#209bfa;font-weight:400}.next-nav.next-line .next-nav-item.next-menu-item.next-selected{background:transparent;color:#209bfa;font-weight:700}.next-nav.next-line .next-nav-item.next-menu-item.next-opened,.next-nav.next-line .next-nav-item.next-menu-item.next-selected.next-nav-item{background:transparent;color:#209bfa}.next-nav.next-line .next-nav-item.next-menu-item.next-child-selected{font-weight:400;background:transparent;color:#209bfa}.next-nav.next-line .next-nav-item.next-menu-item.next-child-selected.next-nav-popup,.next-nav.next-line .next-nav-item.next-menu-item.next-opened.next-nav-popup{color:#209bfa}.next-nav.next-line .next-nav-item.next-menu-item:before,.next-nav.next-line .next-nav-item.next-menu-item:hover:before{background:#209bfa}.next-nav.next-line .next-menu-sub-menu .next-menu-item.next-opened{background:transparent;color:#209bfa}.next-nav.next-line .next-nav-group-label{color:#999;font-weight:400}.next-nav.next-line .next-menu-sub-menu .next-menu-item{background:transparent;color:#333;font-weight:400}.next-nav.next-line .next-menu-sub-menu .next-menu-item.next-focused,.next-nav.next-line .next-menu-sub-menu .next-menu-item.next-selected,.next-nav.next-line .next-menu-sub-menu .next-menu-item.next-selected.next-nav-item,.next-nav.next-line .next-menu-sub-menu .next-menu-item:hover{background:transparent;color:#209bfa}.next-nav.next-line .next-nav-item.next-menu-item.next-disabled,.next-nav.next-line .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a{color:#999;cursor:not-allowed}.next-nav.next-line .next-nav-item.next-menu-item.next-disabled .next-menu-icon-arrow,.next-nav.next-line .next-nav-item.next-menu-item.next-disabled .next-menu-icon-selected,.next-nav.next-line .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-arrow,.next-nav.next-line .next-nav-item.next-menu-item.next-disabled .next-menu-item-text>a .next-menu-icon-selected{color:#999}.next-nav.next-icon-only.next-icon-only-text{padding-top:4px;padding-bottom:4px}.next-nav.next-icon-only.next-custom-icon-only-width{text-align:center}.next-nav.next-icon-only .next-menu-item-inner{text-overflow:clip}.next-nav.next-icon-only.next-normal .next-nav-icon.next-icon{margin-left:2px;margin-right:2px}.next-nav.next-icon-only.next-normal .next-nav-icon.next-icon .next-icon-remote,.next-nav.next-icon-only.next-normal .next-nav-icon.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav.next-icon-only.next-primary .next-nav-icon.next-icon{margin-left:3px;margin-right:3px}.next-nav.next-icon-only.next-primary .next-nav-icon.next-icon .next-icon-remote,.next-nav.next-icon-only.next-primary .next-nav-icon.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav.next-icon-only.next-secondary .next-nav-icon.next-icon{margin-left:3px;margin-right:3px}.next-nav.next-icon-only.next-secondary .next-nav-icon.next-icon .next-icon-remote,.next-nav.next-icon-only.next-secondary .next-nav-icon.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav.next-icon-only .next-nav-icon-only-arrow.next-icon{margin-left:3px;margin-right:3px;transition:all .1s linear;transform-origin:center 50%}.next-nav.next-icon-only .next-nav-icon-only-arrow.next-icon .next-icon-remote,.next-nav.next-icon-only .next-nav-icon-only-arrow.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav.next-icon-only .next-nav-item.next-opened .next-nav-icon-only-arrow.next-icon-arrow-down{transform:rotate(180deg);margin-left:3px;margin-right:3px}.next-nav.next-icon-only .next-nav-item.next-opened .next-nav-icon-only-arrow.next-icon-arrow-down .next-icon-remote,.next-nav.next-icon-only .next-nav-item.next-opened .next-nav-icon-only-arrow.next-icon-arrow-down:before{width:20px;font-size:20px;line-height:inherit}.next-nav.next-icon-only .next-menu-hoz-icon-arrow,.next-nav.next-icon-only .next-menu-icon-arrow{display:none}.next-nav-embeddable.next-normal,.next-nav-embeddable.next-primary,.next-nav-embeddable.next-secondary{height:100%;background:transparent;box-shadow:none;border:none}.next-nav-embeddable.next-normal .next-menu-sub-menu .next-menu-item,.next-nav-embeddable.next-normal .next-nav-item.next-menu-item,.next-nav-embeddable.next-primary .next-menu-sub-menu .next-menu-item,.next-nav-embeddable.next-primary .next-nav-item.next-menu-item,.next-nav-embeddable.next-secondary .next-menu-sub-menu .next-menu-item,.next-nav-embeddable.next-secondary .next-nav-item.next-menu-item{background:transparent}.next-nav-embeddable.next-normal.next-icon-only .next-nav-icon.next-icon,.next-nav-embeddable.next-primary.next-icon-only .next-nav-icon.next-icon,.next-nav-embeddable.next-secondary.next-icon-only .next-nav-icon.next-icon{margin-left:3px;margin-right:3px}.next-nav-embeddable.next-normal.next-icon-only .next-nav-icon.next-icon .next-icon-remote,.next-nav-embeddable.next-normal.next-icon-only .next-nav-icon.next-icon:before,.next-nav-embeddable.next-primary.next-icon-only .next-nav-icon.next-icon .next-icon-remote,.next-nav-embeddable.next-primary.next-icon-only .next-nav-icon.next-icon:before,.next-nav-embeddable.next-secondary.next-icon-only .next-nav-icon.next-icon .next-icon-remote,.next-nav-embeddable.next-secondary.next-icon-only .next-nav-icon.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav-embeddable.next-nav.next-hoz .next-menu-item-inner,.next-nav-embeddable.next-nav.next-hoz .next-menu-sub-menu .next-menu-item,.next-nav-embeddable.next-nav.next-hoz .next-nav-item.next-menu-item{height:100%}.next-nav-embeddable,.next-nav-embeddable .next-nav-item.next-disabled,.next-nav-embeddable .next-nav-item.next-disabled .next-menu-item-text>a{background:transparent;border:none}.next-nav[dir=rtl] .next-nav-icon.next-icon{margin-left:12px;margin-right:0}.next-nav[dir=rtl] .next-nav-icon.next-icon .next-icon-remote,.next-nav[dir=rtl] .next-nav-icon.next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-nav[dir=rtl].next-hoz .next-menu-header{float:right}.next-nav[dir=rtl].next-hoz .next-menu-footer{float:left}.next-nav[dir=rtl].next-hoz .next-nav-item:before{width:0;left:50%}.next-nav[dir=rtl].next-hoz .next-selected.next-nav-item:before{width:100%;left:auto;right:0}.next-nav[dir=rtl].next-ver.next-left .next-nav-item:before{right:0;right:-1px;left:auto}.next-nav[dir=rtl].next-ver.next-right .next-nav-item:before{left:0;left:-1px;right:auto}.next-nav[dir=rtl].next-primary.next-ver.next-left .next-nav-item:before{right:0;left:auto}.next-nav[dir=rtl].next-primary.next-ver.next-right .next-nav-item:before{left:0;right:auto}.next-nav[dir=rtl].next-secondary.next-ver.next-left .next-nav-item:before{right:0;left:auto}.next-nav[dir=rtl].next-secondary.next-ver.next-right .next-nav-item:before{left:0;right:auto}.next-nav[dir=rtl] .next-nav.next-line.next-ver{border-color:transparent}.next-nav[dir=rtl].next-icon-only .next-nav-icon-only-arrow.next-icon,.next-nav[dir=rtl].next-icon-only .next-nav-icon.next-icon,.next-nav[dir=rtl].next-icon-only .next-nav-item.next-opened .next-nav-icon-only-arrow.next-icon-arrow-down{margin-left:0;margin-right:-1px}.next-nav[dir=rtl].next-icon-only .next-nav-icon-only-arrow.next-icon .next-icon-remote,.next-nav[dir=rtl].next-icon-only .next-nav-icon-only-arrow.next-icon:before,.next-nav[dir=rtl].next-icon-only .next-nav-icon.next-icon .next-icon-remote,.next-nav[dir=rtl].next-icon-only .next-nav-icon.next-icon:before,.next-nav[dir=rtl].next-icon-only .next-nav-item.next-opened .next-nav-icon-only-arrow.next-icon-arrow-down .next-icon-remote,.next-nav[dir=rtl].next-icon-only .next-nav-item.next-opened .next-nav-icon-only-arrow.next-icon-arrow-down:before{width:20px;font-size:20px;line-height:inherit}.next-number-picker{display:inline-block}.next-number-picker,.next-number-picker *,.next-number-picker :after,.next-number-picker :before{box-sizing:border-box}.next-number-picker .next-btn{padding:0!important;line-height:0!important;box-shadow:none!important}.next-number-picker-normal .next-input{width:100%}.next-number-picker-normal .next-input .next-input-control{padding-right:0;height:100%}.next-number-picker-normal:not(.next-number-picker-no-trigger) .next-input input{padding-right:2px}.next-number-picker-normal .next-btn{display:block}.next-number-picker-normal .next-btn:hover{z-index:1}.next-number-picker-normal .next-btn:first-child{border-right:none;border-top:none;height:50%;border-top-left-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.next-number-picker-normal .next-btn:last-child{border-right:none;border-bottom:none;margin-top:-1px;height:calc(50% + 1px);border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:0}.next-number-picker-normal .next-number-picker-handler{transition:opacity .1s linear;height:100%;display:block}.next-number-picker-normal:not(.next-number-picker-show-trigger) .next-number-picker-handler{opacity:0}.next-number-picker-normal.hover .next-number-picker-handler,.next-number-picker-normal:hover .next-number-picker-handler{opacity:1}.next-number-picker-normal .next-input.next-disabled .next-number-picker-handler{opacity:0}.next-number-picker-normal .next-number-picker-up-icon:before{content:""}.next-number-picker-normal .next-number-picker-down-icon:before{content:""}.next-number-picker-normal.next-small{width:68px}.next-number-picker-normal.next-small .next-btn{width:20px}.next-number-picker-normal.next-small .next-btn:first-child{border-top-right-radius:3px}.next-number-picker-normal.next-small .next-btn:last-child{border-bottom-right-radius:3px}.next-number-picker-normal.next-small .next-icon .next-icon-remote,.next-number-picker-normal.next-small .next-icon:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-number-picker-normal.next-small .next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-number-picker-normal.next-small .next-icon:before{width:16px;font-size:16px}}.next-number-picker-normal.next-medium{width:80px}.next-number-picker-normal.next-medium .next-btn{width:20px}.next-number-picker-normal.next-medium .next-btn:first-child{border-top-right-radius:3px}.next-number-picker-normal.next-medium .next-btn:last-child{border-bottom-right-radius:3px}.next-number-picker-normal.next-medium .next-icon .next-icon-remote,.next-number-picker-normal.next-medium .next-icon:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-number-picker-normal.next-medium .next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-number-picker-normal.next-medium .next-icon:before{width:16px;font-size:16px}}.next-number-picker-normal.next-large{width:80px}.next-number-picker-normal.next-large .next-btn{width:20px}.next-number-picker-normal.next-large .next-btn:first-child{border-top-right-radius:3px}.next-number-picker-normal.next-large .next-btn:last-child{border-bottom-right-radius:3px}.next-number-picker-normal.next-large .next-icon .next-icon-remote,.next-number-picker-normal.next-large .next-icon:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-number-picker-normal.next-large .next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-number-picker-normal.next-large .next-icon:before{width:16px;font-size:16px}}.next-number-picker-inline input{text-align:center}.next-number-picker-inline .next-input input{padding:0}.next-number-picker-inline .next-number-picker-add-icon:before{content:""}.next-number-picker-inline .next-number-picker-minus-icon:before{content:""}.next-number-picker-inline.next-small{width:68px;min-width:72px}.next-number-picker-inline.next-small .next-icon .next-icon-remote,.next-number-picker-inline.next-small .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-number-picker-inline.next-small .next-btn{height:24px}.next-number-picker-inline.next-small .next-before .next-btn{margin-right:2px;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-number-picker-inline.next-small .next-after .next-btn{margin-left:2px;border-top-right-radius:3px;border-bottom-right-radius:3px}.next-number-picker-inline.next-medium{width:100px;min-width:96px}.next-number-picker-inline.next-medium .next-icon .next-icon-remote,.next-number-picker-inline.next-medium .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-number-picker-inline.next-medium .next-btn{height:32px}.next-number-picker-inline.next-medium .next-before .next-btn{margin-right:2px;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-number-picker-inline.next-medium .next-after .next-btn{margin-left:2px;border-top-right-radius:3px;border-bottom-right-radius:3px}.next-number-picker-inline.next-large{width:128px;min-width:120px}.next-number-picker-inline.next-large .next-icon .next-icon-remote,.next-number-picker-inline.next-large .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-number-picker-inline.next-large .next-btn{height:40px}.next-number-picker-inline.next-large .next-before .next-btn{margin-right:2px;border-top-left-radius:3px;border-bottom-left-radius:3px}.next-number-picker-inline.next-large .next-after .next-btn{margin-left:2px;border-top-right-radius:3px;border-bottom-right-radius:3px}.next-number-picker-inline .next-btn.next-small{width:24px}.next-number-picker-inline .next-btn.next-medium{width:32px}.next-number-picker-inline .next-btn.next-large{width:40px}@-moz-document url-prefix(){.next-number-picker-normal.next-small .next-number-picker-handler{height:22px}.next-number-picker-normal.next-medium .next-number-picker-handler{height:30px}.next-number-picker-normal.next-large .next-number-picker-handler{height:38px}}.next-number-picker-normal[dir=rtl] .next-btn:first-child{border-right:1px solid #ddd;border-left:0;border-top-right-radius:0}.next-number-picker-normal[dir=rtl] .next-btn:first-child.next-large,.next-number-picker-normal[dir=rtl] .next-btn:first-child.next-medium,.next-number-picker-normal[dir=rtl] .next-btn:first-child.next-small{border-top-left-radius:3px}.next-number-picker-normal[dir=rtl] .next-btn:last-child{border-right:1px solid #ddd;border-left:0;border-bottom-right-radius:0}.next-number-picker-normal[dir=rtl] .next-btn:last-child.next-large,.next-number-picker-normal[dir=rtl] .next-btn:last-child.next-medium,.next-number-picker-normal[dir=rtl] .next-btn:last-child.next-small{border-bottom-left-radius:3px}.next-number-picker-normal[dir=rtl] .next-input .next-input-control{padding-left:0}.next-number-picker-inline[dir=rtl] .next-before .next-btn{margin-right:0}.next-number-picker-inline[dir=rtl] .next-before .next-btn.next-large,.next-number-picker-inline[dir=rtl] .next-before .next-btn.next-medium,.next-number-picker-inline[dir=rtl] .next-before .next-btn.next-small{margin-left:2px;border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.next-number-picker-inline[dir=rtl] .next-after .next-btn{margin-left:0}.next-number-picker-inline[dir=rtl] .next-after .next-btn.next-large,.next-number-picker-inline[dir=rtl] .next-after .next-btn.next-medium,.next-number-picker-inline[dir=rtl] .next-after .next-btn.next-small{margin-right:2px;border-top-left-radius:3px!important;border-bottom-left-radius:3px!important}.next-pagination[dir=rtl] .next-pagination-total{margin-right:0;margin-left:16px}.next-pagination[dir=rtl] .next-pagination-jump-go{margin-left:0;margin-right:4px}.next-pagination[dir=rtl] .next-pagination-size-selector-title{margin-right:0;margin-left:4px}.next-pagination[dir=rtl] .next-pagination-size-selector-btn.next-btn-text+.next-pagination-size-selector-btn{border-left:none;border-right:1px solid #e6e6e6}.next-pagination[dir=rtl] .next-pagination-pages+.next-pagination-size-selector,.next-pagination[dir=rtl] .next-pagination-size-selector+.next-pagination-pages{margin-left:0;margin-right:40px}.next-pagination[dir=rtl].next-start .next-pagination-pages{float:left}.next-pagination[dir=rtl].next-end .next-pagination-pages,.next-pagination[dir=rtl].next-start .next-pagination-size-selector{float:right}.next-pagination[dir=rtl].next-end .next-pagination-size-selector{float:left}.next-pagination[dir=rtl].next-small .next-pagination-list{margin:0 4px}.next-pagination[dir=rtl].next-small .next-pagination-total{line-height:24px;vertical-align:middle}.next-pagination[dir=rtl].next-small .next-pagination-item{padding:0 6px;border-width:1px;border-radius:3px}.next-pagination[dir=rtl].next-small .next-pagination-item+.next-pagination-item{margin:0 4px 0 0}.next-pagination[dir=rtl].next-small .next-pagination-ellipsis{height:24px;line-height:24px;margin-left:8px;margin-right:8px}.next-pagination[dir=rtl].next-small .next-pagination-ellipsis .next-icon-remote,.next-pagination[dir=rtl].next-small .next-pagination-ellipsis:before{width:12px;font-size:12px;line-height:inherit}.next-pagination[dir=rtl].next-small .next-pagination-display,.next-pagination[dir=rtl].next-small .next-pagination-display em,.next-pagination[dir=rtl].next-small .next-pagination-jump-text{font-size:12px}.next-pagination[dir=rtl].next-small .next-pagination-jump-input{width:28px}.next-pagination[dir=rtl].next-small .next-pagination-size-selector-title{height:24px;line-height:24px;font-size:12px;vertical-align:middle}.next-pagination[dir=rtl].next-small .next-pagination-size-selector-btn{padding:0 8px}.next-pagination[dir=rtl].next-small .next-pagination-item.next-next:not([disabled]) i,.next-pagination[dir=rtl].next-small .next-pagination-item.next-prev:not([disabled]) i{color:#666}.next-pagination[dir=rtl].next-small .next-pagination-item:hover.next-next:not([disabled]) i,.next-pagination[dir=rtl].next-small .next-pagination-item:hover.next-prev:not([disabled]) i{color:#333}.next-pagination[dir=rtl].next-medium .next-pagination-list{margin:0 4px}.next-pagination[dir=rtl].next-medium .next-pagination-total{line-height:32px;vertical-align:middle}.next-pagination[dir=rtl].next-medium .next-pagination-item{padding:0 10px;border-width:1px;border-radius:3px}.next-pagination[dir=rtl].next-medium .next-pagination-item+.next-pagination-item{margin:0 4px 0 0}.next-pagination[dir=rtl].next-medium .next-pagination-ellipsis{height:32px;line-height:32px;margin-left:8px;margin-right:8px}.next-pagination[dir=rtl].next-medium .next-pagination-ellipsis .next-icon-remote,.next-pagination[dir=rtl].next-medium .next-pagination-ellipsis:before{width:12px;font-size:12px;line-height:inherit}.next-pagination[dir=rtl].next-medium .next-pagination-display,.next-pagination[dir=rtl].next-medium .next-pagination-display em,.next-pagination[dir=rtl].next-medium .next-pagination-jump-text{font-size:14px}.next-pagination[dir=rtl].next-medium .next-pagination-jump-input{width:36px}.next-pagination[dir=rtl].next-medium .next-pagination-size-selector-title{height:32px;line-height:32px;font-size:14px;vertical-align:middle}.next-pagination[dir=rtl].next-medium .next-pagination-size-selector-btn{padding:0 12px}.next-pagination[dir=rtl].next-medium .next-pagination-item.next-next:not([disabled]) i,.next-pagination[dir=rtl].next-medium .next-pagination-item.next-prev:not([disabled]) i{color:#666}.next-pagination[dir=rtl].next-medium .next-pagination-item:hover.next-next:not([disabled]) i,.next-pagination[dir=rtl].next-medium .next-pagination-item:hover.next-prev:not([disabled]) i{color:#333}.next-pagination[dir=rtl].next-large .next-pagination-list{margin:0 8px}.next-pagination[dir=rtl].next-large .next-pagination-total{line-height:40px;vertical-align:middle}.next-pagination[dir=rtl].next-large .next-pagination-item{padding:0 15px;border-width:1px;border-radius:3px}.next-pagination[dir=rtl].next-large .next-pagination-item+.next-pagination-item{margin:0 8px 0 0}.next-pagination[dir=rtl].next-large .next-pagination-ellipsis{height:40px;line-height:40px;margin-left:8px;margin-right:8px}.next-pagination[dir=rtl].next-large .next-pagination-ellipsis .next-icon-remote,.next-pagination[dir=rtl].next-large .next-pagination-ellipsis:before{width:16px;font-size:16px;line-height:inherit}.next-pagination[dir=rtl].next-large .next-pagination-display,.next-pagination[dir=rtl].next-large .next-pagination-display em,.next-pagination[dir=rtl].next-large .next-pagination-jump-text{font-size:16px}.next-pagination[dir=rtl].next-large .next-pagination-jump-input{width:48px}.next-pagination[dir=rtl].next-large .next-pagination-size-selector-title{height:40px;line-height:40px;font-size:16px;vertical-align:middle}.next-pagination[dir=rtl].next-large .next-pagination-size-selector-btn{padding:0 16px}.next-pagination[dir=rtl].next-large .next-pagination-item.next-next:not([disabled]) i,.next-pagination[dir=rtl].next-large .next-pagination-item.next-prev:not([disabled]) i{color:#666}.next-pagination[dir=rtl].next-large .next-pagination-item:hover.next-next:not([disabled]) i,.next-pagination[dir=rtl].next-large .next-pagination-item:hover.next-prev:not([disabled]) i{color:#333}.next-pagination{font-size:0}.next-pagination,.next-pagination *,.next-pagination :after,.next-pagination :before{box-sizing:border-box}.next-pagination:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-pagination-total{display:inline-block;font-size:14px;margin-right:16px}.next-pagination-pages{display:inline-block}.next-pagination-list{display:inline-block;vertical-align:top}.next-pagination .next-pagination-item:not([disabled]){display:inline-block;border-style:solid;border-color:#ddd;background:#fff;color:#333;box-shadow:none}.next-pagination .next-pagination-item{transition:none}.next-pagination .next-pagination-item.next-current{border-color:#209bfa;background:#209bfa;color:#fff;box-shadow:none}.next-pagination .next-pagination-item.next-current:focus,.next-pagination .next-pagination-item.next-current:hover{border-color:#209bfa;background:#fff;color:#209bfa;box-shadow:none}.next-pagination-ellipsis{display:inline-block;color:#999;vertical-align:top}.next-pagination-display{display:inline-block;margin:0 16px;color:#333;vertical-align:middle}.next-pagination-display em{font-style:normal;color:#209bfa}.next-pagination-jump-text{display:inline-block;vertical-align:middle;color:#999}.next-pagination-jump-input{margin:0 4px;vertical-align:top}.next-pagination-jump-go{margin-left:4px;vertical-align:top}.next-pagination-size-selector{display:inline-block;position:relative}.next-pagination-size-selector-title{margin-right:4px;color:#999}.next-pagination-size-selector-filter{display:inline-block;vertical-align:middle}.next-pagination-size-selector-dropdown{vertical-align:top;min-width:64px}.next-pagination-size-selector-dropdown .next-select-inner,.next-pagination-size-selector-popup{min-width:64px}.next-pagination-size-selector-btn.next-btn-text{height:auto;line-height:normal;color:#666;border-radius:0}.next-pagination-size-selector-btn.next-btn-text.next-current{color:#209bfa}.next-pagination-size-selector-btn.next-btn-text+.next-pagination-size-selector-btn{border-left:1px solid #e6e6e6}.next-pagination-pages+.next-pagination-size-selector,.next-pagination-size-selector+.next-pagination-pages{margin-left:40px}.next-pagination.next-hide{display:none}.next-pagination.next-start .next-pagination-pages{float:right}.next-pagination.next-end .next-pagination-pages,.next-pagination.next-start .next-pagination-size-selector{float:left}.next-pagination.next-end .next-pagination-size-selector{float:right}.next-pagination.next-small .next-pagination-list{margin:0 4px}.next-pagination.next-small .next-pagination-total{line-height:24px;vertical-align:middle}.next-pagination.next-small .next-pagination-item{padding:0 6px;border-width:1px;border-radius:3px}.next-pagination.next-small .next-pagination-item+.next-pagination-item{margin:0 0 0 4px}.next-pagination.next-small .next-pagination-ellipsis{height:24px;line-height:24px;margin-left:8px;margin-right:8px}.next-pagination.next-small .next-pagination-ellipsis .next-icon-remote,.next-pagination.next-small .next-pagination-ellipsis:before{width:12px;font-size:12px;line-height:inherit}.next-pagination.next-small .next-pagination-display,.next-pagination.next-small .next-pagination-display em,.next-pagination.next-small .next-pagination-jump-text{font-size:12px}.next-pagination.next-small .next-pagination-jump-input{width:28px}.next-pagination.next-small .next-pagination-size-selector-title{height:24px;line-height:24px;font-size:12px;vertical-align:middle}.next-pagination.next-small .next-pagination-size-selector-btn{padding:0 8px}.next-pagination.next-small .next-pagination-item.next-next:not([disabled]) i,.next-pagination.next-small .next-pagination-item.next-prev:not([disabled]) i{color:#666}.next-pagination.next-small .next-pagination-item:hover.next-next:not([disabled]) i,.next-pagination.next-small .next-pagination-item:hover.next-prev:not([disabled]) i{color:#333}.next-pagination.next-small.next-arrow-only .next-pagination-item.next-next,.next-pagination.next-small.next-arrow-only .next-pagination-item.next-prev{width:20px;padding:0}.next-pagination.next-small.next-arrow-only .next-pagination-item.next-next .next-icon,.next-pagination.next-small.next-arrow-only .next-pagination-item.next-prev .next-icon{margin:0 auto}.next-pagination.next-small.next-arrow-prev-only .next-pagination-item.next-prev{width:20px;padding:0}.next-pagination.next-small.next-arrow-prev-only .next-pagination-item.next-prev .next-icon{margin:0 auto}.next-pagination.next-small.next-no-border .next-pagination-item.next-next,.next-pagination.next-small.next-no-border .next-pagination-item.next-prev{padding:0;border:none;background-color:transparent;box-shadow:none}.next-pagination.next-small.next-no-border .next-pagination-item.next-next .next-icon,.next-pagination.next-small.next-no-border .next-pagination-item.next-prev .next-icon{margin:0}.next-pagination.next-small.next-no-border .next-pagination-item.next-next:not([disabled]):hover i,.next-pagination.next-small.next-no-border .next-pagination-item.next-prev:not([disabled]):hover i{color:#209bfa}.next-pagination.next-small.next-no-border .next-pagination-display{margin:0 8px}.next-pagination.next-small.next-mini .next-pagination-item.next-prev{margin-right:4px}.next-pagination.next-small.next-mini .next-pagination-item.next-next{margin-left:4px}.next-pagination.next-medium .next-pagination-list{margin:0 4px}.next-pagination.next-medium .next-pagination-total{line-height:32px;vertical-align:middle}.next-pagination.next-medium .next-pagination-item{padding:0 10px;border-width:1px;border-radius:3px}.next-pagination.next-medium .next-pagination-item+.next-pagination-item{margin:0 0 0 4px}.next-pagination.next-medium .next-pagination-ellipsis{height:32px;line-height:32px;margin-left:8px;margin-right:8px}.next-pagination.next-medium .next-pagination-ellipsis .next-icon-remote,.next-pagination.next-medium .next-pagination-ellipsis:before{width:12px;font-size:12px;line-height:inherit}.next-pagination.next-medium .next-pagination-display,.next-pagination.next-medium .next-pagination-display em,.next-pagination.next-medium .next-pagination-jump-text{font-size:14px}.next-pagination.next-medium .next-pagination-jump-input{width:36px}.next-pagination.next-medium .next-pagination-size-selector-title{height:32px;line-height:32px;font-size:14px;vertical-align:middle}.next-pagination.next-medium .next-pagination-size-selector-btn{padding:0 12px}.next-pagination.next-medium .next-pagination-item.next-next:not([disabled]) i,.next-pagination.next-medium .next-pagination-item.next-prev:not([disabled]) i{color:#666}.next-pagination.next-medium .next-pagination-item:hover.next-next:not([disabled]) i,.next-pagination.next-medium .next-pagination-item:hover.next-prev:not([disabled]) i{color:#333}.next-pagination.next-medium.next-arrow-only .next-pagination-item.next-next,.next-pagination.next-medium.next-arrow-only .next-pagination-item.next-prev{width:28px;padding:0}.next-pagination.next-medium.next-arrow-only .next-pagination-item.next-next .next-icon,.next-pagination.next-medium.next-arrow-only .next-pagination-item.next-prev .next-icon{margin:0 auto}.next-pagination.next-medium.next-arrow-prev-only .next-pagination-item.next-prev{width:28px;padding:0}.next-pagination.next-medium.next-arrow-prev-only .next-pagination-item.next-prev .next-icon{margin:0 auto}.next-pagination.next-medium.next-no-border .next-pagination-item.next-next,.next-pagination.next-medium.next-no-border .next-pagination-item.next-prev{padding:0;border:none;background-color:transparent;box-shadow:none}.next-pagination.next-medium.next-no-border .next-pagination-item.next-next .next-icon,.next-pagination.next-medium.next-no-border .next-pagination-item.next-prev .next-icon{margin:0}.next-pagination.next-medium.next-no-border .next-pagination-item.next-next:not([disabled]):hover i,.next-pagination.next-medium.next-no-border .next-pagination-item.next-prev:not([disabled]):hover i{color:#209bfa}.next-pagination.next-medium.next-no-border .next-pagination-display{margin:0 12px}.next-pagination.next-medium.next-mini .next-pagination-item.next-prev{margin-right:4px}.next-pagination.next-medium.next-mini .next-pagination-item.next-next{margin-left:4px}.next-pagination.next-large .next-pagination-list{margin:0 8px}.next-pagination.next-large .next-pagination-total{line-height:40px;vertical-align:middle}.next-pagination.next-large .next-pagination-item{padding:0 15px;border-width:1px;border-radius:3px}.next-pagination.next-large .next-pagination-item+.next-pagination-item{margin:0 0 0 8px}.next-pagination.next-large .next-pagination-ellipsis{height:40px;line-height:40px;margin-left:8px;margin-right:8px}.next-pagination.next-large .next-pagination-ellipsis .next-icon-remote,.next-pagination.next-large .next-pagination-ellipsis:before{width:16px;font-size:16px;line-height:inherit}.next-pagination.next-large .next-pagination-display,.next-pagination.next-large .next-pagination-display em,.next-pagination.next-large .next-pagination-jump-text{font-size:16px}.next-pagination.next-large .next-pagination-jump-input{width:48px}.next-pagination.next-large .next-pagination-size-selector-title{height:40px;line-height:40px;font-size:16px;vertical-align:middle}.next-pagination.next-large .next-pagination-size-selector-btn{padding:0 16px}.next-pagination.next-large .next-pagination-item.next-next:not([disabled]) i,.next-pagination.next-large .next-pagination-item.next-prev:not([disabled]) i{color:#666}.next-pagination.next-large .next-pagination-item:hover.next-next:not([disabled]) i,.next-pagination.next-large .next-pagination-item:hover.next-prev:not([disabled]) i{color:#333}.next-pagination.next-large.next-arrow-only .next-pagination-item.next-next,.next-pagination.next-large.next-arrow-only .next-pagination-item.next-prev{width:40px;padding:0}.next-pagination.next-large.next-arrow-only .next-pagination-item.next-next .next-icon,.next-pagination.next-large.next-arrow-only .next-pagination-item.next-prev .next-icon{margin:0 auto}.next-pagination.next-large.next-arrow-prev-only .next-pagination-item.next-prev{width:40px;padding:0}.next-pagination.next-large.next-arrow-prev-only .next-pagination-item.next-prev .next-icon{margin:0 auto}.next-pagination.next-large.next-no-border .next-pagination-item.next-next,.next-pagination.next-large.next-no-border .next-pagination-item.next-prev{padding:0;border:none;background-color:transparent;box-shadow:none}.next-pagination.next-large.next-no-border .next-pagination-item.next-next .next-icon,.next-pagination.next-large.next-no-border .next-pagination-item.next-prev .next-icon{margin:0}.next-pagination.next-large.next-no-border .next-pagination-item.next-next:not([disabled]):hover i,.next-pagination.next-large.next-no-border .next-pagination-item.next-prev:not([disabled]):hover i{color:#209bfa}.next-pagination.next-large.next-no-border .next-pagination-display{margin:0 16px}.next-pagination.next-large.next-mini .next-pagination-item.next-prev{margin-right:8px}.next-pagination.next-large.next-mini .next-pagination-item.next-next{margin-left:8px}.next-pagination-icon-prev:before{content:""}.next-pagination-icon-next:before{content:""}.next-pagination-icon-ellipsis:before{content:""}.next-paragraph{color:#333}.next-paragraph-short{line-height:1.5}.next-paragraph-long{line-height:1.7}.next-paragraph-medium,.next-paragraph-small{font-size:14px}.next-progress-circle[dir=rtl] .next-progress-circle-container{transform:scaleX(-1)}.next-progress-line[dir=rtl] .next-progress-line-overlay{left:auto;right:0}.next-progress-line,.next-progress-line *,.next-progress-line :after,.next-progress-line :before{box-sizing:border-box}.next-progress-line{width:100%;display:inline-block;position:relative}.next-progress-line-container{display:inline-block;width:100%;vertical-align:middle}.next-progress-line-underlay{position:relative;overflow:hidden;width:100%;background:#f5f5f5}.next-progress-line-overlay{position:absolute;left:0;top:0;transition:all .3s ease}.next-progress-line-overlay-normal{background:#209bfa}.next-progress-line-overlay-success{background:#1ad78c}.next-progress-line-overlay-error,.next-progress-line-overlay-started{background:#d23c26}.next-progress-line-overlay-middle{background:#f1c826}.next-progress-line-overlay-finishing{background:#1ad78c}.next-progress-line.next-small .next-progress-line-underlay{border-radius:12px;height:4px}.next-progress-line.next-small .next-progress-line-overlay{height:4px;border-radius:12px;top:50%;margin-top:-2px}.next-progress-line.next-small .next-progress-line-text{font-size:12px;line-height:4px}.next-progress-line.next-medium .next-progress-line-underlay{border-radius:12px;height:8px}.next-progress-line.next-medium .next-progress-line-overlay{height:8px;border-radius:12px;top:50%;margin-top:-4px}.next-progress-line.next-medium .next-progress-line-text{font-size:12px;line-height:8px}.next-progress-line.next-large .next-progress-line-underlay{border-radius:12px;height:12px}.next-progress-line.next-large .next-progress-line-overlay{height:12px;border-radius:12px;top:50%;margin-top:-6px}.next-progress-line.next-large .next-progress-line-text{font-size:14px;line-height:12px}.next-progress-line-show-info .next-progress-line-container{padding-right:60px;margin-right:-60px}.next-progress-line-show-info .next-progress-line-text{width:50px;text-align:left;margin-left:10px;vertical-align:middle;display:inline-block;color:#333}.next-progress-line-show-border .next-progress-line-underlay{border:1px solid #e6e6e6}.next-progress-line-show-border.next-small .next-progress-line-underlay{border-radius:12px;height:6px}.next-progress-line-show-border.next-small .next-progress-line-overlay{height:4px;border-radius:12px;top:50%;margin-top:-2px}.next-progress-line-show-border.next-small .next-progress-line-text{font-size:12px;line-height:6px}.next-progress-line-show-border.next-medium .next-progress-line-underlay{border-radius:12px;height:10px}.next-progress-line-show-border.next-medium .next-progress-line-overlay{height:8px;border-radius:12px;top:50%;margin-top:-4px}.next-progress-line-show-border.next-medium .next-progress-line-text{font-size:12px;line-height:10px}.next-progress-line-show-border.next-large .next-progress-line-underlay{border-radius:12px;height:14px}.next-progress-line-show-border.next-large .next-progress-line-overlay{height:12px;border-radius:12px;top:50%;margin-top:-6px}.next-progress-line-show-border.next-large .next-progress-line-text{font-size:14px;line-height:14px}.next-progress-circle,.next-progress-circle *,.next-progress-circle :after,.next-progress-circle :before{box-sizing:border-box}.next-progress-circle{position:relative;display:inline-block}.next-progress-circle-underlay{stroke-width:8px;stroke:#f5f5f5}.next-progress-circle-overlay{transition:all .3s ease;stroke-linecap:round;stroke-width:8px}.next-progress-circle-overlay-normal{stroke:#209bfa}.next-progress-circle-overlay-success{stroke:#1ad78c}.next-progress-circle-overlay-error,.next-progress-circle-overlay-started{stroke:#d23c26}.next-progress-circle-overlay-middle{stroke:#f1c826}.next-progress-circle-overlay-finishing{stroke:#1ad78c}.next-progress-circle.next-small{width:100px;height:100px;font-size:20px}.next-progress-circle.next-medium{width:116px;height:116px;font-size:24px}.next-progress-circle.next-large{width:132px;height:132px;font-size:36px}.next-progress-circle-text{display:block;position:absolute;width:100%;top:50%;left:0;text-align:center;line-height:1;-webkit-transform:translateY(-50%);transform:translateY(-50%);transition:transform .3s ease;color:#333}.next-range{width:100%;font-family:inherit;font-weight:400;font-size:inherit;line-height:inherit;vertical-align:baseline;display:flex;flex-direction:column;cursor:pointer}.next-range,.next-range *,.next-range :after,.next-range :before{box-sizing:border-box}.next-range .next-range-inner{position:relative}.next-range .next-range-inner:only-child{margin-top:auto;margin-bottom:auto}.next-range .next-range-track{position:absolute;width:100%;top:50%;border-radius:0}.next-range .next-range-selected{position:absolute;width:0;top:50%;left:0;border-radius:0}.next-range .next-range-scale{position:relative;width:100%;height:12px}.next-range .next-range-scale .next-range-scale-item{position:absolute;left:0;width:2px;border:1px solid;border-radius:0}.next-range .next-range-scale .next-range-scale-item:last-child{margin-left:-2px}.next-range .next-range-slider{position:absolute;top:50%;left:0;border-radius:50%}.next-range .next-range-slider-inner{position:absolute;top:50%;left:50%;border:1px solid #ddd;border-radius:50%;transition:transform .1s linear,border-color .1s linear}.next-range .next-range-frag.next-range-active .next-range-slider .next-range-slider-inner,.next-range .next-range-slider.next-range-slider-moving .next-range-slider-inner{border:2px solid #209bfa;box-shadow:4px 4px 8px 0 rgba(0,0,0,.12);transform:scale(1.2)}.next-range .next-range-mark{position:relative;cursor:auto}.next-range .next-range-mark .next-range-mark-text{position:absolute;left:0;transform:translateX(-50%);padding-left:2px;text-align:center}.next-range .next-range-frag{position:absolute;top:0}.next-range .next-range-frag .next-range-slider{left:0}.next-range .next-range-frag .next-range-slider:nth-child(2){left:100%}.next-range .next-range-frag .next-range-selected{width:100%}.next-range.disabled{cursor:not-allowed}.next-range.disabled .next-range-mark{cursor:auto}.next-range .next-range-track,.next-range .next-range-track:hover{background:#ddd}.next-range .next-range-selected,.next-range .next-range-selected:hover{background:#209bfa}.next-range .next-range-scale .next-range-scale-item{border-color:#ddd;background:#ddd}.next-range .next-range-scale .next-range-scale-item:hover{border-color:#ddd}.next-range .next-range-scale .next-range-scale-item.activated{border-color:#209bfa;background:#209bfa}.next-range .next-range-scale .next-range-scale-item.activated:hover{border-color:#209bfa}.next-range .next-range-slider-inner{background:#fff;border-color:#ddd}.next-range .next-range-slider-inner:hover{background:#fff;box-shadow:20px 20px 30px 0 rgba(0,0,0,.15);transform:scale(1.2)}.next-range .next-range-mark .next-range-mark-text,.next-range .next-range-mark .next-range-mark-text:hover{color:#999}.next-range .next-range-mark .next-range-mark-text.activated,.next-range .next-range-mark .next-range-mark-text.activated:hover{color:#333}.next-range.disabled .next-range-track{background:#ddd}.next-range.disabled .next-range-selected{background:#ccc}.next-range.disabled .next-range-scale-item{border-color:#ddd}.next-range.disabled .next-range-scale-item.activated{border-color:#ccc}.next-range.disabled .next-range-slider-inner{background:#eee;border-color:#eee;transform:none;box-shadow:none}.next-range.disabled .next-range-mark-text{color:#ccc}.next-range.disabled .next-range-mark-text.activated{color:#999}.next-range .next-range-selected,.next-range .next-range-track{height:4px;margin-top:-2px}.next-range .next-range-frag{margin-top:4px;height:4px}.next-range .next-range-slider{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12)}.next-range .next-range-slider,.next-range .next-range-slider-inner{height:16px;width:16px;margin-top:-8px;margin-left:-8px}.next-range .next-range-mark{display:block}.next-range .next-range-mark .next-range-mark-text{font-size:14px;font-weight:400;line-height:20px;height:20px}.next-range .next-range-mark.next-range-mark-below{height:30px}.next-range .next-range-mark.next-range-mark-below .next-range-mark-text{bottom:0}.next-range .next-range-mark.next-range-mark-above{height:30px}.next-range .next-range-scale .next-range-scale-item{height:12px}.next-range.simulation-hover>.next-range-slider-inner{background:#fff;box-shadow:20px 20px 30px 0 rgba(0,0,0,.15);transform:scale(1.2)}.next-range.simulation-hover .next-range-selected{background:#209bfa}.next-range.simulation-hover .next-range-track{background:#ddd}.next-range.simulation-hover .next-range-scale-item{border-color:#ddd}.next-range.simulation-hover .next-range-scale-item.activated{border-color:#209bfa}.next-range.simulation-click>.next-range-slider-inner{border:2px solid #209bfa;box-shadow:4px 4px 8px 0 rgba(0,0,0,.12);transform:scale(1.2)}.next-range[dir=rtl] .next-range-mark{position:relative;cursor:auto}.next-range[dir=rtl] .next-range-mark .next-range-mark-text{position:absolute;right:0;transform:translateX(50%);padding-right:2px;text-align:center}.next-rating[dir=rtl] .next-rating-overlay{right:0;left:auto}.next-rating[dir=rtl] .next-rating-overlay .next-rating-icon,.next-rating[dir=rtl] .next-rating-underlay .next-rating-icon{margin-right:4px;margin-left:0}.next-rating[dir=rtl] .next-rating-overlay .next-rating-icon:last-child,.next-rating[dir=rtl] .next-rating-underlay .next-rating-icon:last-child{margin-left:4px}.next-rating{vertical-align:top;display:inline-block;position:relative}.next-rating:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-rating-base,.next-rating-text{float:left}.next-rating-base-disabled,.next-rating-base-disabled .next-rating-overlay .next-rating-icon,.next-rating-base-disabled .next-rating-underlay .next-rating-icon{cursor:not-allowed}.next-rating-symbol-icon:before{content:""}.next-rating-underlay{white-space:nowrap;overflow:hidden}.next-rating-underlay .next-icon{color:#f2f2f2}.next-rating-stroke-mode .next-rating-underlay .next-icon{color:transparent;-webkit-text-stroke:1px #209bfa}.next-rating-overlay{white-space:nowrap;overflow:hidden;position:absolute;width:0;top:0;left:0}.next-rating-overlay .next-icon{color:#209bfa}.next-rating-overlay .next-rating-icon,.next-rating-underlay .next-rating-icon{cursor:pointer;margin-left:4px}.next-rating-overlay .next-rating-icon:last-child,.next-rating-underlay .next-rating-icon:last-child{margin-right:4px}.next-rating-overlay .next-icon,.next-rating-underlay .next-icon{transition:all .1s linear}.next-rating-overlay .next-icon.hover,.next-rating-underlay .next-icon.hover{transform:scale3d(1.1,1.1,1.1)}.next-rating-overlay .next-icon.clicked,.next-rating-underlay .next-icon.clicked{transform:scale3d(.9,.9,.9)}.next-rating-info{position:absolute;top:calc(100% + 4px);left:0;border:1px solid #f2f2f2;background:#fff;padding:4px 8px 3px;font-size:12px;white-space:nowrap}.next-rating-info:after{position:absolute;content:"";width:4px;height:4px;transform:rotate(45deg);background:#fff;border-color:#f2f2f2 transparent transparent #f2f2f2;border-style:solid;border-width:1px;top:-3px;left:4px}.next-rating.hover,.next-rating:focus .next-rating-base:not(.next-rating-base-disabled){outline:none}.next-rating.hover .next-rating-overlay .next-icon,.next-rating:focus .next-rating-base:not(.next-rating-base-disabled) .next-rating-overlay .next-icon{color:#209bfa}.next-rating-grade-low.hover .next-rating-overlay .next-icon,.next-rating-grade-low .next-rating-overlay .next-icon{color:#666}.next-rating-grade-high.hover .next-rating-overlay .next-icon,.next-rating-grade-high .next-rating-overlay .next-icon{color:#209bfa}.next-rating-small{font-size:12px}.next-rating-small .next-icon .next-icon-remote,.next-rating-small .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-rating-small .next-rating-text{margin-left:8px}.next-rating-medium{font-size:14px}.next-rating-medium .next-icon .next-icon-remote,.next-rating-medium .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-rating-medium .next-rating-text{margin-left:12px}.next-rating-large{font-size:16px}.next-rating-large .next-icon .next-icon-remote,.next-rating-large .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-rating-large .next-rating-text{margin-left:16px}.next-search-simple[dir=rtl].next-large .next-search-icon{margin-left:12px;margin-right:0}.next-search-simple[dir=rtl].next-medium .next-search-icon{margin-left:8px;margin-right:0}.next-search-simple[dir=rtl].next-normal .next-search-left .next-search-left-addon{border-left:1px solid #ddd;border-right:none}.next-search-simple[dir=rtl].next-dark .next-search-left{border-color:#666}.next-search-simple[dir=rtl].next-dark .next-search-left .next-search-left-addon{border-right:1px solid #ddd}.next-search-simple[dir=rtl].next-dark:hover .next-search-left{border-color:#999}.next-search-simple[dir=rtl].next-dark .next-search-icon{color:#666}.next-search-simple[dir=rtl].next-dark .next-search-icon:hover{color:#999}.next-search-normal[dir=rtl] .next-search-left{border-left:none;border-top-right-radius:3px;border-bottom-right-radius:3px;border-top-left-radius:0;border-bottom-left-radius:0}.next-search-normal[dir=rtl] .next-search-btn.next-btn{border-radius:3px 0 0 3px!important}.next-search-normal[dir=rtl] .next-input{border-radius:0 3px 3px 0}.next-search-normal[dir=rtl].next-primary .next-input{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px}.next-search-normal[dir=rtl].next-primary .next-search-left .next-search-left-addon{border-left:1px solid #eee;border-right:none}.next-search-normal[dir=rtl].next-secondary .next-input{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px}.next-search-normal[dir=rtl].next-secondary .next-search-left .next-search-left-addon{border-left:1px solid #eee;border-right:none}.next-search-normal[dir=rtl].next-normal .next-input{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px}.next-search-normal[dir=rtl].next-normal .next-search-left .next-search-left-addon{border-left:1px solid #eee;border-right:none}.next-search-normal[dir=rtl].next-dark .next-search-left .next-search-left-addon{border-left:1px solid #209bfa;border-right:none}.next-search{width:100%;display:inline-block}.next-search,.next-search *,.next-search :after,.next-search :before{box-sizing:border-box}.next-search.next-search-focus{box-shadow:none}.next-search.next-search-focus .next-input{background-color:#fff}.next-search.next-search-focus.next-search-normal.next-primary .next-search-left,.next-search.next-search-focus.next-search-normal.next-secondary .next-search-left{border-color:#209bfa}.next-search.next-search-focus.next-search-normal.next-normal .next-search-left{border-color:#ccc}.next-search.next-search-focus.next-search-normal.next-dark .next-search-left{border-color:#209bfa}.next-search.next-search-focus.next-search-simple.next-dark .next-search-left{border-color:#ddd}.next-search.next-search-focus.next-search-simple.next-normal .next-search-left{border-color:#ccc}.next-search .next-input,.next-search .next-select{border:none;box-shadow:none}.next-search .next-select .next-input,.next-search .next-select .next-input .next-input-text-field{height:auto}.next-search .next-search-left{border-style:solid;transition:all .1s linear}.next-search .next-search-left-addon .next-input,.next-search .next-search-left-addon .next-select-trigger-search{min-height:100%;border-bottom-right-radius:0;border-top-right-radius:0}.next-search .next-search-left-addon .next-select-values{line-height:1}.next-search .next-search-left-addon.next-input-group-addon .next-select{margin:0}.next-search .next-search-left-addon+.next-search-input .next-input{border-bottom-left-radius:0;border-top-left-radius:0}.next-search .next-search-input{width:100%}.next-search .next-search-btn{box-shadow:none}.next-search .next-search-symbol-icon:before{content:""}.next-search-normal{width:600px}.next-search-normal .next-search-left{border-top-left-radius:3px;border-bottom-left-radius:3px}.next-search-normal .next-input{border-radius:3px 0 0 3px}.next-search-normal .next-btn{border-radius:0 3px 3px 0}.next-search-normal.next-primary .next-search-left{border-color:#209bfa}.next-search-normal.next-primary .next-search-left .next-search-left-addon{border-right:1px solid #eee}.next-search-normal.next-primary:hover .next-btn,.next-search-normal.next-primary:hover .next-search-left{border-color:#209bfa}.next-search-normal.next-primary .next-search-btn{background:#209bfa;border-color:#209bfa;color:#fff}.next-search-normal.next-primary .next-search-btn:hover{background:#1274e7;border-color:#209bfa;color:#fff}.next-search-normal.next-primary .next-search-btn .next-icon,.next-search-normal.next-primary .next-search-btn .next-icon:hover{color:#fff}.next-search-normal.next-primary.next-large{box-shadow:none}.next-search-normal.next-primary.next-large .next-search-btn,.next-search-normal.next-primary.next-large .next-search-left{border-width:1px;height:40px}.next-search-normal.next-primary.next-large .next-search-input{height:38px;overflow-y:hidden}.next-search-normal.next-primary.next-large .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-primary.next-large .next-select{height:38px}.next-search-normal.next-primary.next-large .next-search-btn{font-size:16px}.next-search-normal.next-primary.next-large .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-primary.next-large .next-search-btn .next-icon:before{width:24px;font-size:24px;line-height:inherit}.next-search-normal.next-primary.next-large .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-primary.next-medium{box-shadow:none}.next-search-normal.next-primary.next-medium .next-search-btn,.next-search-normal.next-primary.next-medium .next-search-left{border-width:1px;height:32px}.next-search-normal.next-primary.next-medium .next-search-input{height:30px;overflow-y:hidden}.next-search-normal.next-primary.next-medium .next-search-input input{height:30px;line-height:30px \0 }.next-search-normal.next-primary.next-medium .next-select{height:30px}.next-search-normal.next-primary.next-medium .next-search-btn{font-size:16px}.next-search-normal.next-primary.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-primary.next-medium .next-search-btn .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-search-normal.next-primary.next-medium .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-primary .next-input{border-top-left-radius:2px;border-bottom-left-radius:2px}.next-search-normal.next-secondary .next-search-left{border-color:#ddd}.next-search-normal.next-secondary .next-search-left .next-search-left-addon{border-right:1px solid #eee}.next-search-normal.next-secondary:hover .next-btn,.next-search-normal.next-secondary:hover .next-search-left{border-color:#209bfa}.next-search-normal.next-secondary .next-search-btn{background:#209bfa;border-color:#209bfa;color:#fff}.next-search-normal.next-secondary .next-search-btn:hover{background:#1274e7;border-color:#209bfa;color:#fff}.next-search-normal.next-secondary .next-search-btn .next-icon,.next-search-normal.next-secondary .next-search-btn .next-icon:hover{color:#fff}.next-search-normal.next-secondary.next-large{box-shadow:none}.next-search-normal.next-secondary.next-large .next-search-btn,.next-search-normal.next-secondary.next-large .next-search-left{border-width:1px;height:40px}.next-search-normal.next-secondary.next-large .next-search-input{height:38px;overflow-y:hidden}.next-search-normal.next-secondary.next-large .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-secondary.next-large .next-select{height:38px}.next-search-normal.next-secondary.next-large .next-search-btn{font-size:16px}.next-search-normal.next-secondary.next-large .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-secondary.next-large .next-search-btn .next-icon:before{width:24px;font-size:24px;line-height:inherit}.next-search-normal.next-secondary.next-large .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-secondary.next-medium{box-shadow:none}.next-search-normal.next-secondary.next-medium .next-search-btn,.next-search-normal.next-secondary.next-medium .next-search-left{border-width:1px;height:32px}.next-search-normal.next-secondary.next-medium .next-search-input{height:30px;overflow-y:hidden}.next-search-normal.next-secondary.next-medium .next-search-input input{height:30px;line-height:30px \0 }.next-search-normal.next-secondary.next-medium .next-select{height:30px}.next-search-normal.next-secondary.next-medium .next-search-btn{font-size:16px}.next-search-normal.next-secondary.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-secondary.next-medium .next-search-btn .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-search-normal.next-secondary.next-medium .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-secondary .next-input{border-top-left-radius:2px;border-bottom-left-radius:2px}.next-search-normal.next-normal .next-search-left{border-color:#ddd}.next-search-normal.next-normal .next-search-left .next-search-left-addon{border-right:1px solid #eee}.next-search-normal.next-normal:hover .next-btn,.next-search-normal.next-normal:hover .next-search-left{border-color:#ccc}.next-search-normal.next-normal .next-search-btn{background:#fafafa;border-color:#ddd;color:#666}.next-search-normal.next-normal .next-search-btn:hover{background:#f5f5f5;border-color:#ccc;color:#333}.next-search-normal.next-normal .next-search-btn .next-icon{color:#666}.next-search-normal.next-normal .next-search-btn .next-icon:hover{color:#333}.next-search-normal.next-normal.next-large{box-shadow:none}.next-search-normal.next-normal.next-large .next-search-btn,.next-search-normal.next-normal.next-large .next-search-left{border-width:1px;height:40px}.next-search-normal.next-normal.next-large .next-search-input{height:38px;overflow-y:hidden}.next-search-normal.next-normal.next-large .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-normal.next-large .next-select{height:38px}.next-search-normal.next-normal.next-large .next-search-btn{font-size:16px}.next-search-normal.next-normal.next-large .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-normal.next-large .next-search-btn .next-icon:before{width:24px;font-size:24px;line-height:inherit}.next-search-normal.next-normal.next-large .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-normal.next-medium{box-shadow:none}.next-search-normal.next-normal.next-medium .next-search-btn,.next-search-normal.next-normal.next-medium .next-search-left{border-width:1px;height:32px}.next-search-normal.next-normal.next-medium .next-search-input{height:30px;overflow-y:hidden}.next-search-normal.next-normal.next-medium .next-search-input input{height:30px;line-height:30px \0 }.next-search-normal.next-normal.next-medium .next-select{height:30px}.next-search-normal.next-normal.next-medium .next-search-btn{font-size:16px}.next-search-normal.next-normal.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-normal.next-medium .next-search-btn .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-search-normal.next-normal.next-medium .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-normal .next-input{border-top-left-radius:2px;border-bottom-left-radius:2px}.next-search-normal.next-dark .next-search-left{border-color:#209bfa}.next-search-normal.next-dark .next-search-left .next-search-left-addon{border-right:1px solid #209bfa}.next-search-normal.next-dark:hover .next-btn,.next-search-normal.next-dark:hover .next-search-left{border-color:#209bfa}.next-search-normal.next-dark .next-search-btn{background:#209bfa;border-color:#209bfa;color:#fff}.next-search-normal.next-dark .next-search-btn:hover{background:#1274e7;border-color:#209bfa;color:#fff}.next-search-normal.next-dark .next-search-btn .next-icon,.next-search-normal.next-dark .next-search-btn .next-icon:hover,.next-search-normal.next-dark .next-select-inner,.next-search-normal.next-dark input{color:#fff}.next-search-normal.next-dark .next-input,.next-search-normal.next-dark .next-select{background:hsla(0,0%,100%,0)}.next-search-normal.next-dark.next-large{box-shadow:none}.next-search-normal.next-dark.next-large .next-search-btn,.next-search-normal.next-dark.next-large .next-search-left{border-width:1px;height:40px}.next-search-normal.next-dark.next-large .next-search-input{height:38px;overflow-y:hidden}.next-search-normal.next-dark.next-large .next-search-input input{height:38px;line-height:38px \0 }.next-search-normal.next-dark.next-large .next-select{height:38px}.next-search-normal.next-dark.next-large .next-search-btn{font-size:16px}.next-search-normal.next-dark.next-large .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-dark.next-large .next-search-btn .next-icon:before{width:24px;font-size:24px;line-height:inherit}.next-search-normal.next-dark.next-large .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal.next-dark.next-medium{box-shadow:none}.next-search-normal.next-dark.next-medium .next-search-btn,.next-search-normal.next-dark.next-medium .next-search-left{border-width:1px;height:32px}.next-search-normal.next-dark.next-medium .next-search-input{height:30px;overflow-y:hidden}.next-search-normal.next-dark.next-medium .next-search-input input{height:30px;line-height:30px \0 }.next-search-normal.next-dark.next-medium .next-select{height:30px}.next-search-normal.next-dark.next-medium .next-search-btn{font-size:16px}.next-search-normal.next-dark.next-medium .next-search-btn .next-icon .next-icon-remote,.next-search-normal.next-dark.next-medium .next-search-btn .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-search-normal.next-dark.next-medium .next-search-btn .next-search-btn-text{display:inline-block;padding-left:0}.next-search-normal:not([dir=rtl]) .next-search-left{border-right:none}.next-search-simple{width:300px;box-shadow:none;border-radius:3px}.next-search-simple .next-search-icon{cursor:pointer;transition:all .1s linear}.next-search-simple .next-input,.next-search-simple .next-search-left{border-radius:3px}.next-search-simple.next-large .next-search-icon{margin-right:12px}.next-search-simple.next-medium .next-search-icon{margin-right:8px}.next-search-simple.next-normal .next-search-left{border-color:#ddd}.next-search-simple.next-normal .next-search-left .next-search-left-addon{border-right:1px solid #ddd}.next-search-simple.next-normal:hover .next-search-left{border-color:#ccc}.next-search-simple.next-normal .next-search-icon{color:#999}.next-search-simple.next-normal .next-search-icon:hover{color:#666}.next-search-simple.next-normal .next-search-left{border-width:1px}.next-search-simple.next-normal.next-large .next-search-icon .next-icon-remote,.next-search-simple.next-normal.next-large .next-search-icon:before{width:20px;font-size:20px;line-height:inherit}.next-search-simple.next-normal.next-medium .next-search-icon .next-icon-remote,.next-search-simple.next-normal.next-medium .next-search-icon:before{width:12px;font-size:12px;line-height:inherit}.next-search-simple.next-dark .next-search-left{border-color:#666}.next-search-simple.next-dark .next-search-left .next-search-left-addon{border-right:1px solid #ddd}.next-search-simple.next-dark:hover .next-search-left{border-color:#999}.next-search-simple.next-dark .next-search-icon{color:#666}.next-search-simple.next-dark .next-search-icon:hover{color:#999}.next-search-simple.next-dark .next-select-inner,.next-search-simple.next-dark input{color:#fff}.next-search-simple.next-dark .next-input,.next-search-simple.next-dark .next-select{background:hsla(0,0%,100%,0)}.next-search-simple.next-dark .next-search-left{border-width:1px}.next-search-simple.next-dark.next-large .next-search-icon .next-icon-remote,.next-search-simple.next-dark.next-large .next-search-icon:before,.next-search-simple.next-dark.next-medium .next-search-icon .next-icon-remote,.next-search-simple.next-dark.next-medium .next-search-icon:before{width:20px;font-size:20px;line-height:inherit}.next-search-simple .next-select.next-large{height:38px}.next-search-simple .next-select.next-medium{height:30px}.next-slick{position:relative;display:block;-webkit-touch-callout:none;user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:rgba(0,0,0,0)}.next-slick,.next-slick *,.next-slick :after,.next-slick :before{box-sizing:border-box}.next-slick-initialized .next-slick-slide{display:block}.next-slick-list{position:relative;overflow:hidden;display:block;margin:0;padding:0;transform:translateZ(0)}.next-slick-list:focus{outline:none}.next-slick-list.dragging{cursor:pointer;cursor:hand}.next-slick-track{position:relative;top:0;left:0;display:block;transform:translateZ(0)}.next-slick-slide{float:left;height:100%;min-height:1px;outline:0;transition:all .1s linear}.next-slick[dir=rtl] .next-slick-slide{float:right}.next-slick-slide img{display:block}.next-slick-arrow{display:block;position:absolute;cursor:pointer;text-align:center;transition:all .1s linear}.next-slick-arrow.inner{color:#fff;background:#000;opacity:.2;padding:0;border:none}.next-slick-arrow.inner:focus,.next-slick-arrow.inner:hover{color:#fff;background:#000;opacity:.4}.next-slick-arrow.inner.disabled{color:#ccc;background:#fafafa;opacity:.5}.next-slick-arrow.outer{color:#666;background:transparent;opacity:.32;padding:0;border:none;border-radius:0}.next-slick-arrow.outer:focus,.next-slick-arrow.outer:hover{color:#333;background:transparent;opacity:.32}.next-slick-arrow.outer.disabled{color:#ccc;background:transparent;opacity:.32}.next-slick-arrow.disabled{cursor:not-allowed}.next-slick-dots{display:block;position:absolute;margin:0;padding:0}.next-slick-dots-item{position:relative;display:inline-block;cursor:pointer}.next-slick-dots-item button{cursor:pointer;border:0 solid #fff;outline:none;padding:0;height:8px;width:8px;border-radius:50%;background:rgba(0,0,0,.32)}.next-slick-dots-item button:focus,.next-slick-dots-item button:hover{background-color:hsla(0,0%,100%,.5);border-color:#fff}.next-slick-dots-item.active button{background:#209bfa;border-color:#fff;animation:zoom .3s cubic-bezier(.86,0,.07,1)}.next-slick-dots.hoz{width:100%;bottom:12px;left:0;text-align:center}.next-slick-dots.hoz .next-slick-dots-item{margin:0 4px}.next-slick-dots.ver{width:16px;top:0;right:20px;bottom:0;display:flex;justify-content:center;flex-direction:column}.next-slick-dots.ver .next-slick-dots-item{margin:0}.next-slick.next-slick-hoz.next-slick-outer{padding:0 24px}.next-slick.next-slick-hoz .next-slick-arrow.medium{width:28px;height:56px;line-height:56px}.next-slick.next-slick-hoz .next-slick-arrow.medium .next-icon .next-icon-remote,.next-slick.next-slick-hoz .next-slick-arrow.medium .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-slick.next-slick-hoz .next-slick-arrow.medium.inner{top:calc(50% - 28px)}.next-slick.next-slick-hoz .next-slick-arrow.medium.inner.next-slick-prev{left:0}.next-slick.next-slick-hoz .next-slick-arrow.medium.inner.next-slick-next{right:0}.next-slick.next-slick-hoz .next-slick-arrow.medium.outer{top:calc(50% - 28px)}.next-slick.next-slick-hoz .next-slick-arrow.medium.outer.next-slick-prev{left:-4px}.next-slick.next-slick-hoz .next-slick-arrow.medium.outer.next-slick-next{right:-4px}.next-slick.next-slick-hoz .next-slick-arrow.large{width:48px;height:96px;line-height:96px}.next-slick.next-slick-hoz .next-slick-arrow.large .next-icon .next-icon-remote,.next-slick.next-slick-hoz .next-slick-arrow.large .next-icon:before{width:32px;font-size:32px;line-height:inherit}.next-slick.next-slick-hoz .next-slick-arrow.large.inner{top:calc(50% - 48px)}.next-slick.next-slick-hoz .next-slick-arrow.large.inner.next-slick-prev{left:0}.next-slick.next-slick-hoz .next-slick-arrow.large.inner.next-slick-next{right:0}.next-slick.next-slick-hoz .next-slick-arrow.large.outer{top:calc(50% - 48px)}.next-slick.next-slick-hoz .next-slick-arrow.large.outer.next-slick-prev{left:-8px}.next-slick.next-slick-hoz .next-slick-arrow.large.outer.next-slick-next{right:-8px}.next-slick.next-slick-ver.next-slick-outer{padding:24px 0}.next-slick.next-slick-ver .next-slick-slide{display:block;height:auto}.next-slick.next-slick-ver .next-slick-arrow.medium{width:56px;height:28px;line-height:28px}.next-slick.next-slick-ver .next-slick-arrow.medium .next-icon .next-icon-remote,.next-slick.next-slick-ver .next-slick-arrow.medium .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-slick.next-slick-ver .next-slick-arrow.medium.inner{left:calc(50% - 28px)}.next-slick.next-slick-ver .next-slick-arrow.medium.inner.next-slick-prev{top:0}.next-slick.next-slick-ver .next-slick-arrow.medium.inner.next-slick-next{bottom:0}.next-slick.next-slick-ver .next-slick-arrow.medium.outer{left:calc(50% - 28px)}.next-slick.next-slick-ver .next-slick-arrow.medium.outer.next-slick-prev{top:-4px}.next-slick.next-slick-ver .next-slick-arrow.medium.outer.next-slick-next{bottom:-4px}.next-slick.next-slick-ver .next-slick-arrow.large{width:96px;height:48px;line-height:48px}.next-slick.next-slick-ver .next-slick-arrow.large .next-icon .next-icon-remote,.next-slick.next-slick-ver .next-slick-arrow.large .next-icon:before{width:32px;font-size:32px;line-height:inherit}.next-slick.next-slick-ver .next-slick-arrow.large.inner{left:calc(50% - 48px)}.next-slick.next-slick-ver .next-slick-arrow.large.inner.next-slick-prev{top:0}.next-slick.next-slick-ver .next-slick-arrow.large.inner.next-slick-next{bottom:0}.next-slick.next-slick-ver .next-slick-arrow.large.outer{left:calc(50% - 48px)}.next-slick.next-slick-ver .next-slick-arrow.large.outer.next-slick-prev{top:-16px}.next-slick.next-slick-ver .next-slick-arrow.large.outer.next-slick-next{bottom:-16px}.next-split-btn{display:inline-block;position:relative}.next-split-btn-spacing-tb{padding:0}.next-split-btn-trigger .next-icon{transition:transform .1s linear}.next-split-btn-trigger.next-expand .next-split-btn-symbol-fold{transform:rotate(180deg)}.next-split-btn-trigger.next-btn-normal:not(:disabled):not(.disabled) .next-icon{color:#999}.next-split-btn-trigger.next-small{padding-left:4px;padding-right:4px}.next-split-btn-trigger.next-medium{padding-left:8px;padding-right:8px}.next-split-btn-symbol-fold:before{content:""}.next-split-btn-symbol-unfold:before{content:""}.next-step,.next-step *,.next-step:after,.next-step :after,.next-step:before,.next-step :before{box-sizing:border-box}.next-step{width:100%;position:relative;border:none}.next-step-item{position:relative;vertical-align:middle;outline:0;height:100%}.next-step-item-body{outline:0}.next-step-item-node{transition:all .1s linear}.next-step-item-node.clicked{transform:scale3d(.8,.8,.8)}.next-step-horizontal{overflow:hidden}.next-step-horizontal>.next-step-item{display:inline-block;text-align:left}.next-step-vertical>.next-step-item{display:block;text-align:center}.next-step-arrow{display:flex}.next-step-arrow .next-step-item{flex:1;height:32px;line-height:32px;margin-left:16px;margin-right:4px}.next-step-arrow .next-step-item:before{content:"";position:absolute;left:-16px;top:0;z-index:1;border:16px solid transparent}.next-step-arrow .next-step-item:after{content:"";position:absolute;right:-16px;top:0;z-index:1;border-top:16px solid transparent;border-bottom:16px solid transparent;border-left:16px solid transparent}.next-step-arrow .next-step-item .next-step-item-container{min-width:100px;height:32px;cursor:pointer}.next-step-arrow .next-step-item .next-step-item-container .next-step-item-title{height:32px;line-height:32px;font-weight:700;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.next-step-arrow>.next-step-item-wait{background:#f5f5f5}.next-step-arrow>.next-step-item-wait .next-step-item-tail-overlay{background:#000}.next-step-arrow>.next-step-item-wait .next-step-item-tail-underlay{background:#ccc}.next-step-arrow>.next-step-item-wait>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-arrow>.next-step-item-wait>.next-step-item-container .next-step-item-node{color:#000}.next-step-arrow>.next-step-item-wait>.next-step-item-container .next-step-item-node-circle,.next-step-arrow>.next-step-item-wait>.next-step-item-container .next-step-item-node-dot{background:#f5f5f5;border-color:#000}.next-step-arrow>.next-step-item-wait .next-step-item-title{color:#999;word-break:break-word}.next-step-arrow>.next-step-item-wait .next-step-item-content{color:#999;font-size:12px;line-height:1.5;word-break:break-word}.next-step-arrow>.next-step-item-wait .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-arrow>.next-step-item-wait .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-arrow>.next-step-item-wait .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-arrow>.next-step-item-wait .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-arrow>.next-step-item-wait .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-arrow>.next-step-item-wait .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-arrow>.next-step-item-wait:before{border:16px solid #f5f5f5;border-left-color:transparent}.next-step-arrow>.next-step-item-wait:after{border-left-color:#f5f5f5}.next-step-arrow>.next-step-item-process{background:#209bfa}.next-step-arrow>.next-step-item-process .next-step-item-tail-overlay{background:#000}.next-step-arrow>.next-step-item-process .next-step-item-tail-underlay{background:#ccc}.next-step-arrow>.next-step-item-process>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-arrow>.next-step-item-process>.next-step-item-container .next-step-item-node{color:#000}.next-step-arrow>.next-step-item-process>.next-step-item-container .next-step-item-node-circle,.next-step-arrow>.next-step-item-process>.next-step-item-container .next-step-item-node-dot{background:#209bfa;border-color:#000}.next-step-arrow>.next-step-item-process .next-step-item-title{color:#fff;word-break:break-word}.next-step-arrow>.next-step-item-process .next-step-item-content{color:#fff;font-size:12px;line-height:1.5;word-break:break-word}.next-step-arrow>.next-step-item-process .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-arrow>.next-step-item-process .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-arrow>.next-step-item-process .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-arrow>.next-step-item-process .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-arrow>.next-step-item-process .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-arrow>.next-step-item-process .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-arrow>.next-step-item-process:before{border:16px solid #209bfa;border-left-color:transparent}.next-step-arrow>.next-step-item-process:after{border-left-color:#209bfa}.next-step-arrow>.next-step-item-finish{background:#add9ff}.next-step-arrow>.next-step-item-finish .next-step-item-tail-overlay{background:#000}.next-step-arrow>.next-step-item-finish .next-step-item-tail-underlay{background:#ccc}.next-step-arrow>.next-step-item-finish>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-arrow>.next-step-item-finish>.next-step-item-container .next-step-item-node{color:#000}.next-step-arrow>.next-step-item-finish>.next-step-item-container .next-step-item-node-circle,.next-step-arrow>.next-step-item-finish>.next-step-item-container .next-step-item-node-dot{background:#add9ff;border-color:#000}.next-step-arrow>.next-step-item-finish .next-step-item-title{color:#209bfa;word-break:break-word}.next-step-arrow>.next-step-item-finish .next-step-item-content{color:#209bfa;font-size:12px;line-height:1.5;word-break:break-word}.next-step-arrow>.next-step-item-finish .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-arrow>.next-step-item-finish .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-arrow>.next-step-item-finish .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-arrow>.next-step-item-finish .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-arrow>.next-step-item-finish .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-arrow>.next-step-item-finish .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-arrow>.next-step-item-finish:before{border:16px solid #add9ff;border-left-color:transparent}.next-step-arrow>.next-step-item-finish:after{border-left-color:#add9ff}.next-step-arrow .next-step-item-disabled{cursor:not-allowed;background:#fafafa}.next-step-arrow .next-step-item-disabled .next-step-item-tail-overlay{background:#000}.next-step-arrow .next-step-item-disabled .next-step-item-tail-underlay{background:#ccc}.next-step-arrow .next-step-item-disabled>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-arrow .next-step-item-disabled>.next-step-item-container .next-step-item-node{color:#000}.next-step-arrow .next-step-item-disabled>.next-step-item-container .next-step-item-node-circle,.next-step-arrow .next-step-item-disabled>.next-step-item-container .next-step-item-node-dot{background:#fafafa;border-color:#000}.next-step-arrow .next-step-item-disabled .next-step-item-title{color:#ccc;word-break:break-word}.next-step-arrow .next-step-item-disabled .next-step-item-content{color:#ccc;font-size:12px;line-height:1.5;word-break:break-word}.next-step-arrow .next-step-item-disabled .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-arrow .next-step-item-disabled .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-arrow .next-step-item-disabled .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-arrow .next-step-item-disabled .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-arrow .next-step-item-disabled .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-arrow .next-step-item-disabled .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-arrow .next-step-item-disabled:before{border:16px solid #fafafa;border-left-color:transparent}.next-step-arrow .next-step-item-disabled:after{border-left-color:#fafafa}.next-step-arrow .next-step-item-disabled .next-step-item-container{cursor:not-allowed}.next-step-arrow .next-step-item-read-only,.next-step-arrow .next-step-item-read-only .next-step-item-container{cursor:default}.next-step-arrow .next-step-item-first{margin-left:0}.next-step-arrow .next-step-item-first:before{border:16px solid transparent}.next-step-arrow .next-step-item-last{margin-right:0}.next-step-arrow .next-step-item-last:after{border:16px solid transparent}.next-step-circle .next-step-item-container{display:inline-block;vertical-align:middle;position:relative;padding:0 8px}.next-step-circle .next-step-item-container .next-step-item-progress .next-progress-circle-text{color:#209bfa;font-size:14px}.next-step-circle .next-step-item-container .next-step-item-progress .next-progress-circle-underlay{stroke:#ccc;stroke-width:3px}.next-step-circle .next-step-item-container .next-step-item-progress .next-progress-circle-overlay-normal{stroke:#209bfa;stroke-width:3px}.next-step-circle .next-step-item-container .next-step-item-node-placeholder{display:inline-block}.next-step-circle>.next-step-item-wait .next-step-item-tail-overlay{background:#ddd}.next-step-circle>.next-step-item-wait .next-step-item-tail-underlay{background:#eee}.next-step-circle>.next-step-item-wait>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-circle>.next-step-item-wait>.next-step-item-container .next-step-item-node{color:#666}.next-step-circle>.next-step-item-wait>.next-step-item-container .next-step-item-node-circle,.next-step-circle>.next-step-item-wait>.next-step-item-container .next-step-item-node-dot{background:#fff;border-color:#ccc}.next-step-circle>.next-step-item-wait .next-step-item-title{color:#666;word-break:break-word}.next-step-circle>.next-step-item-wait .next-step-item-content{color:#666;font-size:12px;line-height:1.5;word-break:break-word}.next-step-circle>.next-step-item-wait .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-circle>.next-step-item-wait .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-circle>.next-step-item-wait .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-circle>.next-step-item-wait .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-circle>.next-step-item-wait .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-circle>.next-step-item-wait .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-circle>.next-step-item-process .next-step-item-tail-overlay{background:#ddd}.next-step-circle>.next-step-item-process .next-step-item-tail-underlay{background:#eee}.next-step-circle>.next-step-item-process>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-circle>.next-step-item-process>.next-step-item-container .next-step-item-node{color:#fff}.next-step-circle>.next-step-item-process>.next-step-item-container .next-step-item-node-circle,.next-step-circle>.next-step-item-process>.next-step-item-container .next-step-item-node-dot{background:#209bfa;border-color:#209bfa}.next-step-circle>.next-step-item-process .next-step-item-title{color:#333;word-break:break-word}.next-step-circle>.next-step-item-process .next-step-item-content{color:#333;font-size:12px;line-height:1.5;word-break:break-word}.next-step-circle>.next-step-item-process .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-circle>.next-step-item-process .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-circle>.next-step-item-process .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-circle>.next-step-item-process .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-circle>.next-step-item-process .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-circle>.next-step-item-process .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-circle>.next-step-item-finish .next-step-item-tail-overlay{background:#209bfa}.next-step-circle>.next-step-item-finish .next-step-item-tail-underlay{background:#eee}.next-step-circle>.next-step-item-finish>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-circle>.next-step-item-finish>.next-step-item-container .next-step-item-node{color:#209bfa}.next-step-circle>.next-step-item-finish>.next-step-item-container .next-step-item-node-circle,.next-step-circle>.next-step-item-finish>.next-step-item-container .next-step-item-node-dot{background:#fff;border-color:#209bfa}.next-step-circle>.next-step-item-finish .next-step-item-title{color:#666;word-break:break-word}.next-step-circle>.next-step-item-finish .next-step-item-content{color:#666;font-size:12px;line-height:1.5;word-break:break-word}.next-step-circle>.next-step-item-finish .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-circle>.next-step-item-finish .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-circle>.next-step-item-finish .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-circle>.next-step-item-finish .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-circle>.next-step-item-finish .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-circle>.next-step-item-finish .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-circle .next-step-item-disabled .next-step-item-tail-overlay,.next-step-circle .next-step-item-disabled .next-step-item-tail-underlay{background:#eee}.next-step-circle .next-step-item-disabled>.next-step-item-container .next-step-item-progress{width:32px;height:32px}.next-step-circle .next-step-item-disabled>.next-step-item-container .next-step-item-node{color:#ccc}.next-step-circle .next-step-item-disabled>.next-step-item-container .next-step-item-node-circle,.next-step-circle .next-step-item-disabled>.next-step-item-container .next-step-item-node-dot{background:#fff;border-color:#eee}.next-step-circle .next-step-item-disabled .next-step-item-title{color:#ccc;word-break:break-word}.next-step-circle .next-step-item-disabled .next-step-item-content{color:#ccc;font-size:12px;line-height:1.5;word-break:break-word}.next-step-circle .next-step-item-disabled .next-step-item-node-placeholder{width:32px;height:32px;position:relative}.next-step-circle .next-step-item-disabled .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-circle .next-step-item-disabled .next-step-item-node-circle{display:block;width:32px;height:32px;font-size:12px;font-weight:400;line-height:30px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-circle .next-step-item-disabled .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-circle .next-step-item-disabled .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-circle .next-step-item-disabled .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-circle .next-step-item-disabled .next-step-item-node,.next-step-circle .next-step-item-disabled .next-step-item-node-placeholder{cursor:not-allowed}.next-step-circle .next-step-item-read-only .next-step-item-node,.next-step-circle .next-step-item-read-only .next-step-item-node-placeholder{cursor:default}.next-step-circle .next-step-item-last .next-step-item-tail{display:none}.next-step-circle.next-step-horizontal{text-align:center;white-space:nowrap}.next-step-circle.next-step-horizontal>.next-step-item .next-step-item-content,.next-step-circle.next-step-horizontal>.next-step-item .next-step-item-title{white-space:normal}.next-step-circle.next-step-horizontal>.next-step-item-wait .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 48px);vertical-align:middle}.next-step-circle.next-step-horizontal>.next-step-item-wait .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-circle.next-step-horizontal>.next-step-item-wait .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-circle.next-step-horizontal>.next-step-item-wait>.next-step-item-body{width:100px;left:-26px;text-align:center;position:absolute}.next-step-circle.next-step-horizontal>.next-step-item-wait>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-circle.next-step-horizontal>.next-step-item-wait>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-circle.next-step-horizontal>.next-step-item-process .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 48px);vertical-align:middle}.next-step-circle.next-step-horizontal>.next-step-item-process .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-circle.next-step-horizontal>.next-step-item-process .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-circle.next-step-horizontal>.next-step-item-process>.next-step-item-body{width:100px;left:-26px;text-align:center;position:absolute}.next-step-circle.next-step-horizontal>.next-step-item-process>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-circle.next-step-horizontal>.next-step-item-process>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-circle.next-step-horizontal>.next-step-item-finish .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 48px);vertical-align:middle}.next-step-circle.next-step-horizontal>.next-step-item-finish .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-circle.next-step-horizontal>.next-step-item-finish .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-circle.next-step-horizontal>.next-step-item-finish>.next-step-item-body{width:100px;left:-26px;text-align:center;position:absolute}.next-step-circle.next-step-horizontal>.next-step-item-finish>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-circle.next-step-horizontal>.next-step-item-finish>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-circle.next-step-horizontal>.next-step-item-disabled .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 48px);vertical-align:middle}.next-step-circle.next-step-horizontal>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-circle.next-step-horizontal>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-circle.next-step-horizontal>.next-step-item-disabled>.next-step-item-body{width:100px;left:-26px;text-align:center;position:absolute}.next-step-circle.next-step-horizontal>.next-step-item-disabled>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-circle.next-step-horizontal>.next-step-item-disabled>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item{vertical-align:unset}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item:last-child .next-step-item-tail{display:none}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item-body{position:relative;display:inline-block;top:0;left:0;max-width:100px;overflow:hidden;vertical-align:top;text-align:left}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item-body .next-step-item-title{display:inline-block;padding-right:8px;margin-top:9px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item-tail{width:calc(100% - 148px);position:absolute;right:0;margin-top:-1px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item:last-child .next-step-item-tail{display:none}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item-body{position:relative;display:inline-block;top:0;left:0;max-width:100px;overflow:hidden;vertical-align:top;text-align:left}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item-body .next-step-item-title{display:inline-block;padding-right:8px;margin-top:9px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item-tail{width:calc(100% - 148px);position:absolute;right:0;margin-top:-1px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item:last-child .next-step-item-tail{display:none}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item-body{position:relative;display:inline-block;top:0;left:0;max-width:100px;overflow:hidden;vertical-align:top;text-align:left}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item-body .next-step-item-title{display:inline-block;padding-right:8px;margin-top:9px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item-tail{width:calc(100% - 148px);position:absolute;right:0;margin-top:-1px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item:last-child .next-step-item-tail{display:none}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item-body{position:relative;display:inline-block;top:0;left:0;max-width:100px;overflow:hidden;vertical-align:top;text-align:left}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item-body .next-step-item-title{display:inline-block;padding-right:8px;margin-top:9px}.next-step-circle.next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item-tail{width:calc(100% - 148px);position:absolute;right:0;margin-top:-1px}.next-step-circle.next-step-vertical{font-size:0;display:table-cell;vertical-align:middle;position:relative}.next-step-circle.next-step-vertical .next-step-item-container{padding:0}.next-step-circle.next-step-vertical>.next-step-item:last-child .next-step-item-tail{display:block;visibility:hidden}.next-step-circle.next-step-vertical>.next-step-item-wait .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-circle.next-step-vertical>.next-step-item-wait .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-circle.next-step-vertical>.next-step-item-wait .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-circle.next-step-vertical>.next-step-item-wait>.next-step-item-body{position:absolute;top:0;left:16px;margin-left:8px}.next-step-circle.next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-title{margin-top:8px;text-align:left;font-weight:700;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle.next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-content{margin-top:4px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-circle.next-step-vertical>.next-step-item-process .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-circle.next-step-vertical>.next-step-item-process .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-circle.next-step-vertical>.next-step-item-process .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-circle.next-step-vertical>.next-step-item-process>.next-step-item-body{position:absolute;top:0;left:16px;margin-left:8px}.next-step-circle.next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-title{margin-top:8px;text-align:left;font-weight:700;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle.next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-content{margin-top:4px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-circle.next-step-vertical>.next-step-item-finish .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-circle.next-step-vertical>.next-step-item-finish .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-circle.next-step-vertical>.next-step-item-finish .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-circle.next-step-vertical>.next-step-item-finish>.next-step-item-body{position:absolute;top:0;left:16px;margin-left:8px}.next-step-circle.next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-title{margin-top:8px;text-align:left;font-weight:700;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle.next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-content{margin-top:4px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-circle.next-step-vertical>.next-step-item-disabled .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-circle.next-step-vertical>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-circle.next-step-vertical>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-circle.next-step-vertical>.next-step-item-disabled>.next-step-item-body{position:absolute;top:0;left:16px;margin-left:8px}.next-step-circle.next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-title{margin-top:8px;text-align:left;font-weight:700;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle.next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-content{margin-top:4px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-dot .next-step-item-container{display:inline-block;vertical-align:middle;position:relative;padding:0 8px;margin-top:-1px;margin-bottom:-1px}.next-step-dot .next-step-item-container .next-step-item-node-placeholder{display:inline-block}.next-step-dot .next-step-item-container .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-dot .next-step-item-container .next-step-item-node .next-icon .next-icon-remote,.next-step-dot .next-step-item-container .next-step-item-node .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-dot>.next-step-item-wait .next-step-item-tail-overlay{background:#ddd}.next-step-dot>.next-step-item-wait .next-step-item-tail-underlay{background:#eee}.next-step-dot>.next-step-item-wait>.next-step-item-container .next-step-item-progress{width:12px;height:12px}.next-step-dot>.next-step-item-wait>.next-step-item-container .next-step-item-node{color:#999}.next-step-dot>.next-step-item-wait>.next-step-item-container .next-step-item-node-circle,.next-step-dot>.next-step-item-wait>.next-step-item-container .next-step-item-node-dot{background:#fff;border-color:#ccc}.next-step-dot>.next-step-item-wait .next-step-item-title{color:#666;word-break:break-word}.next-step-dot>.next-step-item-wait .next-step-item-content{color:#666;line-height:1.5;word-break:break-word}.next-step-dot>.next-step-item-wait .next-step-item-node-placeholder{width:12px;height:12px;position:relative}.next-step-dot>.next-step-item-wait .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-dot>.next-step-item-wait .next-step-item-node-circle{display:block;width:12px;height:12px;font-size:12px;font-weight:400;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-dot>.next-step-item-wait .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-dot>.next-step-item-wait .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-dot>.next-step-item-wait .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-dot>.next-step-item-wait .next-step-item-content{font-size:12px}.next-step-dot>.next-step-item-wait .next-step-item-node-dot{display:block;width:12px;height:12px;font-size:12px;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .3s ease,border-color .3s ease}.next-step-dot>.next-step-item-process .next-step-item-tail-overlay{background:#ddd}.next-step-dot>.next-step-item-process .next-step-item-tail-underlay{background:#eee}.next-step-dot>.next-step-item-process>.next-step-item-container .next-step-item-progress{width:12px;height:12px}.next-step-dot>.next-step-item-process>.next-step-item-container .next-step-item-node{color:#209bfa}.next-step-dot>.next-step-item-process>.next-step-item-container .next-step-item-node-circle,.next-step-dot>.next-step-item-process>.next-step-item-container .next-step-item-node-dot{background:#209bfa;border-color:#209bfa}.next-step-dot>.next-step-item-process .next-step-item-title{color:#333;word-break:break-word}.next-step-dot>.next-step-item-process .next-step-item-content{color:#333;line-height:1.5;word-break:break-word}.next-step-dot>.next-step-item-process .next-step-item-node-placeholder{width:12px;height:12px;position:relative}.next-step-dot>.next-step-item-process .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-dot>.next-step-item-process .next-step-item-node-circle{display:block;width:12px;height:12px;font-size:12px;font-weight:400;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-dot>.next-step-item-process .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-dot>.next-step-item-process .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-dot>.next-step-item-process .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-dot>.next-step-item-process .next-step-item-content{font-size:12px}.next-step-dot>.next-step-item-process .next-step-item-node-dot{display:block;width:12px;height:12px;font-size:12px;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .3s ease,border-color .3s ease}.next-step-dot>.next-step-item-finish .next-step-item-tail-overlay{background:#209bfa}.next-step-dot>.next-step-item-finish .next-step-item-tail-underlay{background:#eee}.next-step-dot>.next-step-item-finish>.next-step-item-container .next-step-item-progress{width:12px;height:12px}.next-step-dot>.next-step-item-finish>.next-step-item-container .next-step-item-node{color:#209bfa}.next-step-dot>.next-step-item-finish>.next-step-item-container .next-step-item-node-circle,.next-step-dot>.next-step-item-finish>.next-step-item-container .next-step-item-node-dot{background:#fff;border-color:#209bfa}.next-step-dot>.next-step-item-finish .next-step-item-title{color:#666;word-break:break-word}.next-step-dot>.next-step-item-finish .next-step-item-content{color:#666;line-height:1.5;word-break:break-word}.next-step-dot>.next-step-item-finish .next-step-item-node-placeholder{width:12px;height:12px;position:relative}.next-step-dot>.next-step-item-finish .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-dot>.next-step-item-finish .next-step-item-node-circle{display:block;width:12px;height:12px;font-size:12px;font-weight:400;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-dot>.next-step-item-finish .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-dot>.next-step-item-finish .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-dot>.next-step-item-finish .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-dot>.next-step-item-finish .next-step-item-content{font-size:12px}.next-step-dot>.next-step-item-finish .next-step-item-node-dot{display:block;width:12px;height:12px;font-size:12px;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .3s ease,border-color .3s ease}.next-step-dot .next-step-item-disabled .next-step-item-tail-overlay,.next-step-dot .next-step-item-disabled .next-step-item-tail-underlay{background:#eee}.next-step-dot .next-step-item-disabled>.next-step-item-container .next-step-item-progress{width:12px;height:12px}.next-step-dot .next-step-item-disabled>.next-step-item-container .next-step-item-node{color:#eee}.next-step-dot .next-step-item-disabled>.next-step-item-container .next-step-item-node-circle,.next-step-dot .next-step-item-disabled>.next-step-item-container .next-step-item-node-dot{background:#fff;border-color:#e6e6e6}.next-step-dot .next-step-item-disabled .next-step-item-title{color:#ccc;word-break:break-word}.next-step-dot .next-step-item-disabled .next-step-item-content{color:#ccc;line-height:1.5;word-break:break-word}.next-step-dot .next-step-item-disabled .next-step-item-node-placeholder{width:12px;height:12px;position:relative}.next-step-dot .next-step-item-disabled .next-step-item-node{position:relative;display:inline-block;text-align:center;cursor:pointer}.next-step-dot .next-step-item-disabled .next-step-item-node-circle{display:block;width:12px;height:12px;font-size:12px;font-weight:400;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .1s linear}.next-step-dot .next-step-item-disabled .next-step-item-node-circle .next-icon{animation:zoomIn .3s linear}.next-step-dot .next-step-item-disabled .next-step-item-node-circle .next-icon .next-icon-remote,.next-step-dot .next-step-item-disabled .next-step-item-node-circle .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-step-dot .next-step-item-disabled .next-step-item-content{font-size:12px}.next-step-dot .next-step-item-disabled .next-step-item-node-dot{display:block;width:12px;height:12px;font-size:12px;line-height:10px;text-align:center;border:1px solid;border-radius:50%;transition:background-color .3s ease,border-color .3s ease}.next-step-dot .next-step-item-disabled .next-step-item-node,.next-step-dot .next-step-item-disabled .next-step-item-node-placeholder{cursor:not-allowed}.next-step-dot .next-step-item-read-only .next-step-item-node,.next-step-dot .next-step-item-read-only .next-step-item-node-placeholder{cursor:default}.next-step-dot .next-step-item-last .next-step-item-tail{display:none}.next-step-dot.next-step-horizontal{text-align:center;white-space:nowrap}.next-step-dot.next-step-horizontal>.next-step-item .next-step-item-content,.next-step-dot.next-step-horizontal>.next-step-item .next-step-item-title{white-space:normal}.next-step-dot.next-step-horizontal .next-step-item-node .next-icon{vertical-align:middle}.next-step-dot.next-step-horizontal>.next-step-item-wait .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 28px);vertical-align:middle}.next-step-dot.next-step-horizontal>.next-step-item-wait .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-dot.next-step-horizontal>.next-step-item-wait .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-dot.next-step-horizontal>.next-step-item-wait>.next-step-item-body{width:100px;left:-36px;text-align:center;position:absolute}.next-step-dot.next-step-horizontal>.next-step-item-wait>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-dot.next-step-horizontal>.next-step-item-wait>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-dot.next-step-horizontal>.next-step-item-process .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 28px);vertical-align:middle}.next-step-dot.next-step-horizontal>.next-step-item-process .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-dot.next-step-horizontal>.next-step-item-process .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-dot.next-step-horizontal>.next-step-item-process>.next-step-item-body{width:100px;left:-36px;text-align:center;position:absolute}.next-step-dot.next-step-horizontal>.next-step-item-process>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-dot.next-step-horizontal>.next-step-item-process>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-dot.next-step-horizontal>.next-step-item-finish .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 28px);vertical-align:middle}.next-step-dot.next-step-horizontal>.next-step-item-finish .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-dot.next-step-horizontal>.next-step-item-finish .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-dot.next-step-horizontal>.next-step-item-finish>.next-step-item-body{width:100px;left:-36px;text-align:center;position:absolute}.next-step-dot.next-step-horizontal>.next-step-item-finish>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-dot.next-step-horizontal>.next-step-item-finish>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-dot.next-step-horizontal>.next-step-item-disabled .next-step-item-tail{display:inline-block;clear:both;width:calc(100% - 28px);vertical-align:middle}.next-step-dot.next-step-horizontal>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-underlay{display:block;height:1px;position:relative}.next-step-dot.next-step-horizontal>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:1px;transition:all .1s linear;width:100%}.next-step-dot.next-step-horizontal>.next-step-item-disabled>.next-step-item-body{width:100px;left:-36px;text-align:center;position:absolute}.next-step-dot.next-step-horizontal>.next-step-item-disabled>.next-step-item-body>.next-step-item-title{font-size:14px;line-height:18px;margin-top:8px;font-weight:700}.next-step-dot.next-step-horizontal>.next-step-item-disabled>.next-step-item-body>.next-step-item-content{margin-top:4px}.next-step-dot.next-step-vertical{padding:0 0 0 4px;font-size:0;display:table-cell;position:relative}.next-step-dot.next-step-vertical .next-step-item-container{padding:0}.next-step-dot.next-step-vertical>.next-step-item:last-child .next-step-item-tail{display:block;visibility:hidden}.next-step-dot.next-step-vertical>.next-step-item-wait .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-dot.next-step-vertical>.next-step-item-wait .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-dot.next-step-vertical>.next-step-item-wait .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-dot.next-step-vertical>.next-step-item-wait>.next-step-item-body{position:absolute;top:0;left:6px;margin-left:8px}.next-step-dot.next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-title{margin-top:0;font-weight:700;text-align:left;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot.next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-content{margin-top:8px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-dot.next-step-vertical>.next-step-item-process .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-dot.next-step-vertical>.next-step-item-process .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-dot.next-step-vertical>.next-step-item-process .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-dot.next-step-vertical>.next-step-item-process>.next-step-item-body{position:absolute;top:0;left:6px;margin-left:8px}.next-step-dot.next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-title{margin-top:0;font-weight:700;text-align:left;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot.next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-content{margin-top:8px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-dot.next-step-vertical>.next-step-item-finish .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-dot.next-step-vertical>.next-step-item-finish .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-dot.next-step-vertical>.next-step-item-finish .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-dot.next-step-vertical>.next-step-item-finish>.next-step-item-body{position:absolute;top:0;left:6px;margin-left:8px}.next-step-dot.next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-title{margin-top:0;font-weight:700;text-align:left;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot.next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-content{margin-top:8px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-dot.next-step-vertical>.next-step-item-disabled .next-step-item-tail{width:1px;height:0;margin:8px auto}.next-step-dot.next-step-vertical>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-underlay{height:100%;width:1px;position:relative}.next-step-dot.next-step-vertical>.next-step-item-disabled .next-step-item-tail .next-step-item-tail-overlay{position:absolute;top:0;height:100%;width:1px}.next-step-dot.next-step-vertical>.next-step-item-disabled>.next-step-item-body{position:absolute;top:0;left:6px;margin-left:8px}.next-step-dot.next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-title{margin-top:0;font-weight:700;text-align:left;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot.next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-content{margin-top:8px;min-height:8px;text-align:left;font-size:12px;line-height:1.5}.next-step-horizontal[dir=rtl]>.next-step-item{text-align:right}.next-step-arrow[dir=rtl] .next-step-item{height:32px;line-height:32px;margin-left:4px;margin-right:16px}.next-step-arrow[dir=rtl] .next-step-item:before{right:-16px;left:auto;border:16px solid transparent}.next-step-arrow[dir=rtl] .next-step-item:after{left:-32px;right:auto;border-top:16px solid transparent;border-bottom:16px solid transparent;border-right:16px solid transparent}.next-step-arrow[dir=rtl]>.next-step-item-wait{background:#f5f5f5}.next-step-arrow[dir=rtl]>.next-step-item-wait .next-step-item-node-dot{right:50%;left:auto}.next-step-arrow[dir=rtl]>.next-step-item-wait:before{border:16px solid #f5f5f5;border-right-color:transparent}.next-step-arrow[dir=rtl]>.next-step-item-wait:after{border-right-color:#f5f5f5;border-left-color:transparent}.next-step-arrow[dir=rtl]>.next-step-item-process{background:#209bfa}.next-step-arrow[dir=rtl]>.next-step-item-process .next-step-item-node-dot{right:50%;left:auto}.next-step-arrow[dir=rtl]>.next-step-item-process:before{border:16px solid #209bfa;border-right-color:transparent}.next-step-arrow[dir=rtl]>.next-step-item-process:after{border-right-color:#209bfa;border-left-color:transparent}.next-step-arrow[dir=rtl]>.next-step-item-finish{background:#add9ff}.next-step-arrow[dir=rtl]>.next-step-item-finish .next-step-item-node-dot{right:50%;left:auto}.next-step-arrow[dir=rtl]>.next-step-item-finish:before{border:16px solid #add9ff;border-right-color:transparent}.next-step-arrow[dir=rtl]>.next-step-item-finish:after{border-right-color:#add9ff;border-left-color:transparent}.next-step-arrow[dir=rtl] .next-step-item-disabled{background:#fafafa}.next-step-arrow[dir=rtl] .next-step-item-disabled .next-step-item-node-dot{right:50%;left:auto}.next-step-arrow[dir=rtl] .next-step-item-disabled:before{border:16px solid #fafafa;border-right-color:transparent}.next-step-arrow[dir=rtl] .next-step-item-disabled:after{border-right-color:#fafafa;border-left-color:transparent}.next-step-arrow[dir=rtl] .next-step-item-first{margin-right:0}.next-step-arrow[dir=rtl] .next-step-item-last{margin-left:0}.next-step-circle[dir=rtl] .next-step-item-disabled .next-step-item-node-dot,.next-step-circle[dir=rtl]>.next-step-item-finish .next-step-item-node-dot,.next-step-circle[dir=rtl]>.next-step-item-process .next-step-item-node-dot,.next-step-circle[dir=rtl]>.next-step-item-wait .next-step-item-node-dot{right:50%;left:auto}.next-step-circle[dir=rtl].next-step-horizontal>.next-step-item-disabled>.next-step-item-body,.next-step-circle[dir=rtl].next-step-horizontal>.next-step-item-finish>.next-step-item-body,.next-step-circle[dir=rtl].next-step-horizontal>.next-step-item-process>.next-step-item-body,.next-step-circle[dir=rtl].next-step-horizontal>.next-step-item-wait>.next-step-item-body{right:-26px;left:auto}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item-body{left:auto;right:0;text-align:right}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item-body .next-step-item-title{padding-left:8px;padding-right:0}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-wait .next-step-item-tail{left:0;right:auto}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item-body{left:auto;right:0;text-align:right}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item-body .next-step-item-title{padding-left:8px;padding-right:0}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-process .next-step-item-tail{left:0;right:auto}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item-body{left:auto;right:0;text-align:right}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item-body .next-step-item-title{padding-left:8px;padding-right:0}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-finish .next-step-item-tail{left:0;right:auto}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item-body{left:auto;right:0;text-align:right}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item-body .next-step-item-title{padding-left:8px;padding-right:0}.next-step-circle[dir=rtl].next-step-horizontal.next-step-label-horizontal>.next-step-item-disabled .next-step-item-tail{left:0;right:auto}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-wait>.next-step-item-body{right:16px;left:auto;margin-right:8px;margin-left:0}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-process>.next-step-item-body{right:16px;left:auto;margin-right:8px;margin-left:0}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-finish>.next-step-item-body{right:16px;left:auto;margin-right:8px;margin-left:0}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-disabled>.next-step-item-body{right:16px;left:auto;margin-right:8px;margin-left:0}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-circle[dir=rtl].next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-dot[dir=rtl] .next-step-item-disabled .next-step-item-node-dot,.next-step-dot[dir=rtl]>.next-step-item-finish .next-step-item-node-dot,.next-step-dot[dir=rtl]>.next-step-item-process .next-step-item-node-dot,.next-step-dot[dir=rtl]>.next-step-item-wait .next-step-item-node-dot{right:50%;left:auto}.next-step-dot[dir=rtl].next-step-horizontal>.next-step-item-disabled>.next-step-item-body,.next-step-dot[dir=rtl].next-step-horizontal>.next-step-item-finish>.next-step-item-body,.next-step-dot[dir=rtl].next-step-horizontal>.next-step-item-process>.next-step-item-body,.next-step-dot[dir=rtl].next-step-horizontal>.next-step-item-wait>.next-step-item-body{right:-36px;left:auto}.next-step-dot[dir=rtl].next-step-vertical{padding:0 4px 0 0}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-wait>.next-step-item-body{right:6px;left:auto;margin-right:8px;margin-left:0}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-wait>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-process>.next-step-item-body{right:6px;left:auto;margin-right:8px;margin-left:0}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-process>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-finish>.next-step-item-body{right:6px;left:auto;margin-right:8px;margin-left:0}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-finish>.next-step-item-body>.next-step-item-content{text-align:right}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-disabled>.next-step-item-body{right:6px;left:auto;margin-right:8px;margin-left:0}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-title{text-align:right;font-family:Roboto,Helvetica Neue,Helvetica,Tahoma,Arial,PingFang SC,Microsoft YaHei;font-size:14px;line-height:1.2857142}.next-step-dot[dir=rtl].next-step-vertical>.next-step-item-disabled>.next-step-item-body>.next-step-item-content{text-align:right}.next-switch:after[dir=rtl]{content:" ";transition:all .1s linear;transform-origin:right center}.next-switch-medium[dir=rtl]:after,.next-switch-small[dir=rtl]:after{right:100%;transform:translateX(100%)}.next-switch-on[dir=rtl]>.next-switch-children{color:#fff}.next-switch-on[disabled][dir=rtl]:after{left:0;right:100%;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12)}.next-switch-off[dir=rtl]:after{right:0;transform:translateX(0);box-shadow:-1px 0 3px 0 rgba(0,0,0,.12)}.next-switch-off.next-switch-small[dir=rtl]>.next-switch-children,.next-switch-off[dir=rtl]>.next-switch-children{right:auto}.next-switch{outline:none;text-align:left;cursor:pointer;vertical-align:middle;user-select:none;overflow:hidden;transition:background .1s cubic-bezier(.4,0,.2,1),border-color .1s cubic-bezier(.4,0,.2,1)}.next-switch,.next-switch *,.next-switch :after,.next-switch :before{box-sizing:border-box}.next-switch-btn{transition:all .15s cubic-bezier(.4,0,.2,1);transform-origin:left center}.next-switch:after{content:""}.next-switch-loading{pointer-events:none}.next-switch-loading .next-icon-loading{color:#209bfa;text-align:center;transform:translate(-1px,-1px)}.next-switch-loading .next-icon-loading.next-switch-inner-icon:before{vertical-align:top}.next-switch-medium{position:relative;display:inline-block;border:2px solid transparent;width:48px;height:28px;border-radius:12px}.next-switch-medium:not([disabled]):active .next-switch-btn{width:31.2px}.next-switch-medium.next-switch-on:not([disabled]):active .next-switch-btn{left:calc(100% - 31.2px)}.next-switch-medium.next-switch-auto-width{min-width:48px;width:auto;overflow:initial}.next-switch-medium:after{content:""}.next-switch-medium>.next-switch-btn{border:1px solid transparent;position:absolute;left:calc(100% - 24px);width:24px;height:24px;border-radius:12px;box-sizing:border-box}.next-switch-medium>.next-switch-children{height:24px;line-height:24px;font-size:14px}.next-switch-medium.next-switch.next-switch-on>.next-switch-children{margin:0 32px 0 8px}.next-switch-medium.next-switch.next-switch-off>.next-switch-children{margin:0 8px 0 32px}.next-switch-medium.next-switch-loading .next-icon-loading{line-height:24px;height:24px;width:24px}.next-switch-medium.next-switch-loading .next-icon-loading .next-icon-remote,.next-switch-medium.next-switch-loading .next-icon-loading:before{width:16px;font-size:16px;line-height:inherit}.next-switch-small{position:relative;display:inline-block;border:2px solid transparent;width:44px;height:24px;border-radius:12px}.next-switch-small:not([disabled]):active .next-switch-btn{width:26px}.next-switch-small.next-switch-on:not([disabled]):active .next-switch-btn{left:calc(100% - 26px)}.next-switch-small.next-switch-auto-width{min-width:44px;width:auto;overflow:initial}.next-switch-small:after{content:""}.next-switch-small>.next-switch-btn{border:1px solid transparent;position:absolute;left:calc(100% - 20px);width:20px;height:20px;border-radius:12px;box-sizing:border-box}.next-switch-small>.next-switch-children{height:20px;line-height:20px;font-size:12px}.next-switch-small.next-switch.next-switch-on>.next-switch-children{margin:0 28px 0 8px}.next-switch-small.next-switch.next-switch-off>.next-switch-children{margin:0 8px 0 28px}.next-switch-small.next-switch-loading .next-icon-loading{line-height:20px;height:20px;width:20px}.next-switch-small.next-switch-loading .next-icon-loading .next-icon-remote,.next-switch-small.next-switch-loading .next-icon-loading:before{width:12px;font-size:12px;line-height:inherit}.next-switch-on{background-color:#209bfa}.next-switch-on .next-switch-btn{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fff;border-color:transparent}.next-switch-on>.next-switch-children{color:#fff}.next-switch-on.hover,.next-switch-on:focus,.next-switch-on:hover{background-color:#1274e7}.next-switch-on.hover .next-switch-btn,.next-switch-on:focus .next-switch-btn,.next-switch-on:hover .next-switch-btn{background-color:#fff}.next-switch-on[disabled]{background-color:#f5f5f5;cursor:not-allowed}.next-switch-on[disabled] .next-switch-btn{right:0;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fafafa;border-color:transparent}.next-switch-on[disabled]>.next-switch-children{color:#ccc}.next-switch-off,.next-switch-off.hover,.next-switch-off:focus,.next-switch-off:hover{background-color:#f5f5f5;border-color:#f5f5f5}.next-switch-off .next-switch-btn{left:0;box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fff;border-color:transparent}.next-switch-off.hover .next-switch-btn,.next-switch-off:focus .next-switch-btn,.next-switch-off:hover .next-switch-btn{background-color:#fff}.next-switch-off>.next-switch-children{color:#999}.next-switch-off[disabled]{background-color:#f5f5f5;cursor:not-allowed}.next-switch-off[disabled] .next-switch-btn{box-shadow:1px 1px 3px 0 rgba(0,0,0,.12);background-color:#fafafa;border-color:transparent}.next-switch-off[disabled]>.next-switch-children{color:#ddd}.next-tabs{width:100%}.next-tabs,.next-tabs *,.next-tabs :after,.next-tabs :before{box-sizing:border-box}.next-tabs-bar{outline:none}.next-tabs-bar-popup{overflow-y:auto;max-height:480px}.next-tabs-nav-container{position:relative}.next-tabs-nav-container:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-tabs-nav-wrap{overflow:hidden}.next-tabs-nav-scroll{overflow:hidden;white-space:nowrap}.next-tabs-scrollable .next-tabs-nav-scroll{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}.next-tabs-scrollable .next-tabs-nav-scroll::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;-webkit-appearance:none;opacity:0!important}.next-tabs-nav{display:inline-block;position:relative;transition:all .3s ease;list-style:none;padding:0;margin:0}.next-tabs-nav-appear,.next-tabs-nav-enter{animation:fadeInLeft .4s cubic-bezier(.78,.14,.15,.86);animation-fill-mode:both}.next-tabs-nav-leave{animation:fadeOutLeft .2s cubic-bezier(.78,.14,.15,.86);animation-fill-mode:both}.next-tabs-nav.next-disable-animation .next-tabs-tab:before{transition:none}.next-tabs-tab{display:inline-block;position:relative;transition:all .1s linear}.next-tabs-tab-inner{position:relative;cursor:pointer;text-decoration:none}.next-tabs-tab:before{content:"";position:absolute;transition:all .3s ease}.next-tabs-tab.active{font-weight:400}.next-tabs-tab .next-tabs-tab-close{color:#666}.next-tabs-tab .next-tabs-tab-close:hover{color:#333}.next-tabs-tab .next-tabs-tab-close:focus{outline:none}.next-tabs-tab.active .next-tabs-tab-close{color:#209bfa}.next-tabs-tab.disabled .next-tabs-tab-close{color:#e6e6e6}.next-tabs-tab:focus{outline:none}.next-tabs-tabpane{visibility:hidden;opacity:0}.next-tabs-tabpane.active{visibility:visible;opacity:1;height:auto}.next-tabs-tabpane.hidden{overflow:hidden;height:0!important;margin:0!important;padding:0!important;border:0!important}.next-tabs-btn-down,.next-tabs-btn-next,.next-tabs-btn-prev{position:absolute;top:0;cursor:pointer;padding:0;border:0;outline:none;height:100%;background:transparent;border-color:transparent}.next-tabs-btn-down,.next-tabs-btn-down.visited,.next-tabs-btn-down:link,.next-tabs-btn-down:visited,.next-tabs-btn-next,.next-tabs-btn-next.visited,.next-tabs-btn-next:link,.next-tabs-btn-next:visited,.next-tabs-btn-prev,.next-tabs-btn-prev.visited,.next-tabs-btn-prev:link,.next-tabs-btn-prev:visited{color:#666}.next-tabs-btn-down.active,.next-tabs-btn-down.hover,.next-tabs-btn-down:active,.next-tabs-btn-down:focus,.next-tabs-btn-down:hover,.next-tabs-btn-next.active,.next-tabs-btn-next.hover,.next-tabs-btn-next:active,.next-tabs-btn-next:focus,.next-tabs-btn-next:hover,.next-tabs-btn-prev.active,.next-tabs-btn-prev.hover,.next-tabs-btn-prev:active,.next-tabs-btn-prev:focus,.next-tabs-btn-prev:hover{color:#333;background:transparent;border-color:transparent;text-decoration:none}.next-tabs-btn-down.disabled,.next-tabs-btn-next.disabled,.next-tabs-btn-prev.disabled{cursor:not-allowed;color:#e6e6e6}.next-tabs-btn-next{right:8px}.next-tabs-btn-prev{right:32px}.next-tabs-btn-down{right:8px}.next-tabs .next-tab-icon-dropdown:before{content:""}.next-tabs .next-tab-icon-prev:before{content:""}.next-tabs .next-tab-icon-next:before{content:""}.next-tabs-content{overflow:hidden}.next-tabs-vertical>.next-tabs-bar .next-tabs-nav{width:100%}.next-tabs-vertical>.next-tabs-bar .next-tabs-tab{display:block}.next-tabs.next-medium .next-tabs-nav-container-scrolling{padding-right:60px}.next-tabs.next-medium .next-tabs-tab-inner{font-size:14px;padding:20px 16px}.next-tabs.next-medium .next-tabs-tab-inner .next-icon{line-height:1}.next-tabs.next-medium .next-tabs-tab-inner .next-icon .next-icon-remote,.next-tabs.next-medium .next-tabs-tab-inner .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-tabs.next-medium .next-tabs-tab-inner .next-tabs-tab-close .next-icon-remote,.next-tabs.next-medium .next-tabs-tab-inner .next-tabs-tab-close:before{width:12px;font-size:12px;line-height:inherit}.next-tabs.next-medium .next-tabs-tab-inner .next-tabs-tab-close.next-icon{margin-left:8px}.next-tabs.next-medium .next-tabs-tab-inner .next-icon-add .next-icon-remote,.next-tabs.next-medium .next-tabs-tab-inner .next-icon-add:before{width:12px;font-size:12px;line-height:inherit}.next-tabs.next-medium .next-tabs-btn-down .next-icon .next-icon-remote,.next-tabs.next-medium .next-tabs-btn-down .next-icon:before,.next-tabs.next-medium .next-tabs-btn-next .next-icon .next-icon-remote,.next-tabs.next-medium .next-tabs-btn-next .next-icon:before,.next-tabs.next-medium .next-tabs-btn-prev .next-icon .next-icon-remote,.next-tabs.next-medium .next-tabs-btn-prev .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-tabs.next-small .next-tabs-nav-container-scrolling{padding-right:56px}.next-tabs.next-small .next-tabs-tab-inner{font-size:12px;padding:8px 12px}.next-tabs.next-small .next-tabs-tab-inner .next-icon{line-height:1}.next-tabs.next-small .next-tabs-tab-inner .next-icon .next-icon-remote,.next-tabs.next-small .next-tabs-tab-inner .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-tabs.next-small .next-tabs-tab-inner .next-tabs-tab-close .next-icon-remote,.next-tabs.next-small .next-tabs-tab-inner .next-tabs-tab-close:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-tabs.next-small .next-tabs-tab-inner .next-tabs-tab-close{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-tabs.next-small .next-tabs-tab-inner .next-tabs-tab-close:before{width:16px;font-size:16px}}.next-tabs.next-small .next-tabs-tab-inner .next-tabs-tab-close.next-icon{margin-left:8px}.next-tabs.next-small .next-tabs-tab-inner .next-icon-add .next-icon-remote,.next-tabs.next-small .next-tabs-tab-inner .next-icon-add:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-tabs.next-small .next-tabs-tab-inner .next-icon-add{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-tabs.next-small .next-tabs-tab-inner .next-icon-add:before{width:16px;font-size:16px}}.next-tabs.next-small .next-tabs-btn-down .next-icon .next-icon-remote,.next-tabs.next-small .next-tabs-btn-down .next-icon:before,.next-tabs.next-small .next-tabs-btn-next .next-icon .next-icon-remote,.next-tabs.next-small .next-tabs-btn-next .next-icon:before,.next-tabs.next-small .next-tabs-btn-prev .next-icon .next-icon-remote,.next-tabs.next-small .next-tabs-btn-prev .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-tabs-show-add{position:relative;display:flex;flex:none;align-items:center;padding-right:0!important}.next-tabs-show-add .next-tabs-nav-wrap{position:relative;display:flex;flex:auto;align-self:stretch;overflow:hidden;white-space:nowrap}.next-tabs-show-add .next-tabs-nav-wrap:after{position:absolute;height:100%;width:1px;right:0;content:"";pointer-events:none;box-shadow:-2px 0 3px 0 rgba(0,0,0,.12);z-index:1}.next-tabs-show-add .next-tabs-nav-operations{display:flex;align-self:stretch}.next-tabs-show-add .next-tabs-nav-operations .next-tabs-btn-prev{position:static;right:auto}.next-tabs-show-add .next-tabs-nav-operations .next-tabs-btn-down,.next-tabs-show-add .next-tabs-nav-operations .next-tabs-btn-next{position:static;margin-left:8px;right:auto}.next-tabs.next-small .next-tabs-nav-operations .next-tabs-btn-prev{margin-left:8px}.next-tabs.next-small .next-tabs-nav-operations .next-tabs-btn-next{margin-right:8px}.next-tabs.next-medium .next-tabs-nav-operations .next-tabs-btn-prev{margin-left:12px}.next-tabs.next-medium .next-tabs-nav-operations .next-tabs-btn-next{margin-right:12px}.next-tabs-pure>.next-tabs-bar{border-bottom:1px solid #e6e6e6;background-color:transparent}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container{margin-bottom:-1px;box-shadow:none}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab{color:#666;background-color:transparent}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab:hover{cursor:pointer;color:#333;background-color:transparent}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab.active{z-index:1;color:#209bfa;background-color:transparent}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab.disabled{pointer-events:none;cursor:default;color:#e6e6e6;background:transparent}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab:before{border-radius:0;width:0;border-bottom:2px solid #209bfa;left:50%;bottom:0}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-container .next-tabs-tab.active:before{width:100%;left:0}.next-tabs-wrapped>.next-tabs-bar{background:transparent}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab{color:#666;background-color:#f9f9f9}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab:hover{cursor:pointer;color:#333;background-color:#f5f5f5}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.active{z-index:1;color:#209bfa;background-color:#fff}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.disabled{pointer-events:none;cursor:default;color:#ccc;background:#fafafa}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab .next-tabs-tab-close{color:#666}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab .next-tabs-tab-close:hover{color:#333}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab .next-tabs-tab-close:focus{outline:none}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.active .next-tabs-tab-close{color:#209bfa}.next-tabs-wrapped>.next-tabs-bar .next-tabs-tab.disabled .next-tabs-tab-close{color:#e6e6e6}.next-tabs-wrapped:after,.next-tabs-wrapped:before{content:"";display:table}.next-tabs-wrapped:after{clear:both}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar,.next-tabs-wrapped>.next-tabs-content{position:relative}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-nav-extra{position:absolute;top:50%;right:0;transform:translateY(-50%)}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab{border-radius:3px 3px 0 0;border:1px solid #e6e6e6}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab+.next-tabs-tab{margin-left:4px}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab:hover{border-color:#ddd}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab.active{border-color:#e6e6e6 #e6e6e6 #fff}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab:before{border-radius:3px;width:0;border-top:2px solid #209bfa;left:50%;top:-1px}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab.active:before{width:calc(100% - 6px);left:3px}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-tab.active{border-width:1px}.next-tabs-wrapped.next-tabs-top>.next-tabs-bar:before{content:"";position:absolute;top:100%;width:100%;height:0;border-bottom:1px solid #e6e6e6;transform:translateY(-1px);display:block}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar{position:relative}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-nav-extra{position:absolute;top:50%;right:0;transform:translateY(-50%)}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab{margin-right:4px;border:1px solid #e6e6e6;border-radius:0 0 3px 3px}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab:hover{border-color:#ddd}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab.active{border-color:#fff #e6e6e6 #e6e6e6}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab:before{border-radius:3px;width:0;border-bottom:2px solid #209bfa;left:50%;bottom:-1px}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-tab.active:before{width:calc(100% - 6px);left:3px}.next-tabs-wrapped.next-tabs-bottom>.next-tabs-content{top:1px;border-bottom:1px solid #e6e6e6}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar{float:left}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab{float:none;margin-bottom:4px;border-radius:3px 0 0 3px;border:1px solid #e6e6e6}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab:hover{border-color:#ddd}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab.active{border-color:#e6e6e6 #fff #e6e6e6 #e6e6e6}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab:before{border-radius:3px;height:0;border-left:2px solid #209bfa;top:50%;left:-1px}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab.active:before{height:calc(100% - 6px);top:3px}.next-tabs-wrapped.next-tabs-left>.next-tabs-bar .next-tabs-tab.active{border-width:1px}.next-tabs-wrapped.next-tabs-left>.next-tabs-content{right:1px;border-left:1px solid #e6e6e6}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar{float:right}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab{float:none;margin-bottom:4px;border-radius:0 3px 3px 0;border:1px solid #e6e6e6}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab:hover{border-color:#ddd}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab.active{border-color:#e6e6e6 #e6e6e6 #e6e6e6 #fff}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab:before{border-radius:3px;height:0;border-right:2px solid #209bfa;top:50%;right:-1px}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab.active:before{height:calc(100% - 6px);top:3px}.next-tabs-wrapped.next-tabs-right>.next-tabs-bar .next-tabs-tab.active{border-width:1px}.next-tabs-wrapped.next-tabs-right>.next-tabs-content{right:-1px;border-right:1px solid #e6e6e6}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab{transition:background-color .1s linear;border:1px solid #ddd;border-right-color:transparent;margin-right:-1px;color:#333;background-color:#f9f9f9}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab:first-child{border-radius:3px 0 0 3px}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab:last-child{border-radius:0 3px 3px 0;border-right:1px solid #ddd;margin-right:0}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.active{border-right:1px solid;border-color:#209bfa}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.disabled{border-color:#eee}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab:hover{z-index:2;border-right:1px solid;border-color:#ddd;cursor:pointer;color:#333;background-color:#f5f5f5}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.active{z-index:1;color:#fff;background-color:#209bfa}.next-tabs-capsule>.next-tabs-bar .next-tabs-tab.disabled{pointer-events:none;cursor:default;color:#ccc;background:#fafafa}.next-tabs-text>.next-tabs-bar .next-tabs-tab{color:#666;background-color:transparent}.next-tabs-text>.next-tabs-bar .next-tabs-tab:hover{cursor:pointer;color:#333;background-color:transparent}.next-tabs-text>.next-tabs-bar .next-tabs-tab.active{z-index:1;color:#209bfa;background-color:transparent}.next-tabs-text>.next-tabs-bar .next-tabs-tab.disabled{pointer-events:none;cursor:default;color:#ccc;background:transparent}.next-tabs-text>.next-tabs-bar .next-tabs-tab:not(:last-child):after{content:"";position:absolute;right:0;top:calc(50% - 4px);width:1px;height:8px;background-color:#e6e6e6}.next-tabs-pure>.next-tabs-bar{position:relative}.next-tabs-pure>.next-tabs-bar .next-tabs-nav-extra{position:absolute;top:50%;right:0;transform:translateY(-50%)}.next-tabs-capsule>.next-tabs-bar{position:relative}.next-tabs-capsule>.next-tabs-bar .next-tabs-nav-extra{position:absolute;top:50%;right:0;transform:translateY(-50%)}.next-tabs-text>.next-tabs-bar{position:relative}.next-tabs-text>.next-tabs-bar .next-tabs-nav-extra{position:absolute;top:50%;right:0;transform:translateY(-50%)}.next-tabs[dir=rtl].next-medium .next-tabs-nav-container-scrolling{padding-left:60px;padding-right:0}.next-tabs[dir=rtl].next-medium .next-tabs-tab-close{padding-right:8px;padding-left:0}.next-tabs[dir=rtl].next-small .next-tabs-nav-container-scrolling{padding-left:56px;padding-right:0}.next-tabs[dir=rtl].next-small .next-tabs-tab-close{padding-right:8px;padding-left:0}.next-tabs[dir=rtl].next-tabs-wrapped.next-tabs-bottom>.next-tabs-bar .next-tabs-nav-extra,.next-tabs[dir=rtl].next-tabs-wrapped.next-tabs-top>.next-tabs-bar .next-tabs-nav-extra,.next-tabs[dir=rtl]>.next-tabs-bar .next-tabs-nav-extra{right:auto;left:0}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab{border:1px solid #ddd;border-left:0}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab:first-child{border-left:0;border-radius:0 3px 3px 0}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab:last-child{border-radius:3px 0 0 3px;border-left:1px solid #ddd}.next-tabs[dir=rtl].next-tabs-capsule>.next-tabs-bar .next-tabs-tab.active{margin-left:-1px;margin-right:auto;border-left:1px solid;border-color:#209bfa}.next-tabs[dir=rtl] .next-tabs-btn-next{left:8px;right:auto}.next-tabs[dir=rtl] .next-tabs-btn-prev{left:32px;right:auto}.next-tabs[dir=rtl] .next-tabs-btn-down{left:8px;right:auto}.next-tabs-text[dir=rtl]>.next-tabs-bar .next-tabs-tab:not(:last-child):after{content:"";position:absolute;left:0;right:auto}@keyframes fadeInRightForTag{0%{opacity:0;transform:rotate(45deg) translateX(20px)}to{opacity:1;transform:rotate(45deg) translateX(0)}}.next-tag>.next-tag-body{overflow:hidden;text-overflow:ellipsis}.next-tag-checkable.next-tag-level-secondary{color:#333;border-color:transparent;background-color:transparent}.next-tag-checkable.next-tag-level-secondary:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-secondary:not(.disabled):not([disabled]):hover{color:#209bfa}.next-tag-default.next-tag-level-primary{color:#666;border-color:#f5f5f5;background-color:#f5f5f5}.next-tag-default.next-tag-level-primary:not(.disabled):not([disabled]).hover,.next-tag-default.next-tag-level-primary:not(.disabled):not([disabled]):hover{color:#333;border-color:#f2f2f2;background-color:#f2f2f2}.next-tag-default.next-tag-level-primary:not(.disabled):not([disabled]).hover>.next-tag-close-btn,.next-tag-default.next-tag-level-primary:not(.disabled):not([disabled]):hover>.next-tag-close-btn{color:#333}.disabled.next-tag-default.next-tag-level-primary,[disabled].next-tag-default.next-tag-level-primary{color:#ccc;border-color:#fafafa;background-color:#fafafa}.disabled.next-tag-default.next-tag-level-primary>.next-tag-close-btn,[disabled].next-tag-default.next-tag-level-primary>.next-tag-close-btn{color:#ccc}.next-tag-default.next-tag-level-primary>.next-tag-close-btn{color:#666}.next-tag-closable.next-tag-level-primary{color:#666;border-color:#f5f5f5;background-color:#f5f5f5}.next-tag-closable.next-tag-level-primary:not(.disabled):not([disabled]).hover,.next-tag-closable.next-tag-level-primary:not(.disabled):not([disabled]):hover{color:#333;border-color:#f2f2f2;background-color:#f2f2f2}.next-tag-closable.next-tag-level-primary:not(.disabled):not([disabled]).hover>.next-tag-close-btn,.next-tag-closable.next-tag-level-primary:not(.disabled):not([disabled]):hover>.next-tag-close-btn{color:#333}.disabled.next-tag-closable.next-tag-level-primary,[disabled].next-tag-closable.next-tag-level-primary{color:#ccc;border-color:#fafafa;background-color:#fafafa}.disabled.next-tag-closable.next-tag-level-primary>.next-tag-close-btn,[disabled].next-tag-closable.next-tag-level-primary>.next-tag-close-btn{color:#ccc}.next-tag-closable.next-tag-level-primary>.next-tag-close-btn{color:#666}.next-tag-checkable.next-tag-level-primary{color:#666;border-color:#f5f5f5;background-color:#f5f5f5}.next-tag-checkable.next-tag-level-primary:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-primary:not(.disabled):not([disabled]):hover{color:#333;border-color:#f2f2f2;background-color:#f2f2f2}.next-tag-checkable.next-tag-level-primary:not(.disabled):not([disabled]).hover>.next-tag-close-btn,.next-tag-checkable.next-tag-level-primary:not(.disabled):not([disabled]):hover>.next-tag-close-btn{color:#333}.disabled.next-tag-checkable.next-tag-level-primary,[disabled].next-tag-checkable.next-tag-level-primary{color:#ccc;border-color:#fafafa;background-color:#fafafa}.disabled.next-tag-checkable.next-tag-level-primary>.next-tag-close-btn,[disabled].next-tag-checkable.next-tag-level-primary>.next-tag-close-btn{color:#ccc}.next-tag-checkable.next-tag-level-primary>.next-tag-close-btn{color:#666}.next-tag-checkable.next-tag-level-primary.checked{color:#fff;border-color:#209bfa;background-color:#209bfa}.next-tag-checkable.next-tag-level-primary.checked:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-primary.checked:not(.disabled):not([disabled]):hover{color:#fff;border-color:#1274e7;background-color:#1274e7}.next-tag-checkable.next-tag-level-primary.checked:not(.disabled):not([disabled]).hover>.next-tag-close-btn,.next-tag-checkable.next-tag-level-primary.checked:not(.disabled):not([disabled]):hover>.next-tag-close-btn{color:#fff}.disabled.next-tag-checkable.next-tag-level-primary.checked,[disabled].next-tag-checkable.next-tag-level-primary.checked{color:#ccc;border-color:#fafafa;background-color:#fafafa}.disabled.next-tag-checkable.next-tag-level-primary.checked>.next-tag-close-btn,.next-tag-checkable.next-tag-level-primary.checked>.next-tag-close-btn,[disabled].next-tag-checkable.next-tag-level-primary.checked>.next-tag-close-btn{color:#fff}.next-tag-default.next-tag-level-normal{color:#666;border-color:#ddd;background-color:transparent}.next-tag-default.next-tag-level-normal:not(.disabled):not([disabled]).hover,.next-tag-default.next-tag-level-normal:not(.disabled):not([disabled]):hover{color:#333;border-color:#ccc;background-color:transparent}.next-tag-default.next-tag-level-normal:not(.disabled):not([disabled]).hover>.next-tag-close-btn,.next-tag-default.next-tag-level-normal:not(.disabled):not([disabled]):hover>.next-tag-close-btn{color:#333}.disabled.next-tag-default.next-tag-level-normal,[disabled].next-tag-default.next-tag-level-normal{color:#ccc;border-color:#eee;background-color:#fafafa}.disabled.next-tag-default.next-tag-level-normal>.next-tag-close-btn,[disabled].next-tag-default.next-tag-level-normal>.next-tag-close-btn{color:#ccc}.next-tag-default.next-tag-level-normal>.next-tag-close-btn{color:#666}.next-tag-closable.next-tag-level-normal{color:#666;border-color:#ddd;background-color:transparent}.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]).hover,.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]):hover{color:#333;border-color:#ccc;background-color:transparent}.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]).hover>.next-tag-close-btn,.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]):hover>.next-tag-close-btn{color:#333}.disabled.next-tag-closable.next-tag-level-normal,[disabled].next-tag-closable.next-tag-level-normal{color:#ccc;border-color:#eee;background-color:transparent}.disabled.next-tag-closable.next-tag-level-normal>.next-tag-close-btn,[disabled].next-tag-closable.next-tag-level-normal>.next-tag-close-btn{color:#ccc}.next-tag-closable.next-tag-level-normal>.next-tag-close-btn{color:#666}.next-tag-checkable.next-tag-level-normal.checked{color:#209bfa;border-color:#209bfa;background-color:transparent}.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]):hover{color:#1274e7;border-color:#1274e7;background-color:transparent}.next-tag-checkable.next-tag-level-secondary.checked{color:#209bfa;border-color:#209bfa;background-color:transparent}.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]):hover{color:#1274e7;border-color:#1274e7;background-color:transparent}.next-tag-checkable.next-tag-level-secondary.checked:before{position:absolute;content:"";-webkit-font-smoothing:antialiased;background-color:#209bfa;transform:rotate(45deg)}.next-tag-checkable.next-tag-level-secondary.checked:after{position:absolute;font-family:NextIcon;-webkit-font-smoothing:antialiased;content:"";transform:scale(.6);color:#fff}.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]).hover:before,.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]):hover:before{background-color:#1274e7}.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]).hover:after,.next-tag-checkable.next-tag-level-secondary.checked:not(.disabled):not([disabled]):hover:after{color:#fff}.next-tag-checkable.next-tag-level-secondary.checked:disabled:before,[disabled].next-tag-checkable.next-tag-level-secondary.checked:before{background-color:#eee}.next-tag-checkable.next-tag-level-secondary.checked:disabled:after,[disabled].next-tag-checkable.next-tag-level-secondary.checked:after{color:#fff}.next-tag-checkable.next-tag-level-normal{color:#666;border-color:#ddd;background-color:transparent}.next-tag-checkable.next-tag-level-normal:not(.disabled):not([disabled]).hover,.next-tag-checkable.next-tag-level-normal:not(.disabled):not([disabled]):hover{color:#333;border-color:#ddd;background-color:transparent}.disabled.next-tag-checkable.next-tag-level-normal,[disabled].next-tag-checkable.next-tag-level-normal{color:#ccc;border-color:#eee;background-color:#fafafa}.next-tag-checkable.next-tag-level-normal.checked:before{position:absolute;content:"";-webkit-font-smoothing:antialiased;background-color:#209bfa;transform:rotate(45deg)}.next-tag-checkable.next-tag-level-normal.checked:after{position:absolute;font-family:NextIcon;-webkit-font-smoothing:antialiased;content:"";transform:scale(.6);color:#fff}.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]).hover:before,.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]):hover:before{background-color:#1274e7}.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]).hover:after,.next-tag-checkable.next-tag-level-normal.checked:not(.disabled):not([disabled]):hover:after{color:#fff}.next-tag-checkable.next-tag-level-normal.checked:disabled:before,[disabled].next-tag-checkable.next-tag-level-normal.checked:before{background-color:#eee}.next-tag-checkable.next-tag-level-normal.checked:disabled:after,[disabled].next-tag-checkable.next-tag-level-normal.checked:after{color:#fff}.next-tag-closable.next-tag-level-normal:before{position:absolute;content:"";-webkit-font-smoothing:antialiased;background-color:#ddd;transform:rotate(45deg)}.next-tag-closable.next-tag-level-normal:after{position:absolute;font-family:NextIcon;-webkit-font-smoothing:antialiased;content:"";transform:scale(.6);color:#fff}.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]).hover:before,.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]):hover:before{background-color:#ccc}.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]).hover:after,.next-tag-closable.next-tag-level-normal:not(.disabled):not([disabled]):hover:after{color:#fff}.next-tag-closable.next-tag-level-normal:disabled:before,[disabled].next-tag-closable.next-tag-level-normal:before{background-color:#eee}.next-tag-closable.next-tag-level-normal:disabled:after,[disabled].next-tag-closable.next-tag-level-normal:after{color:#fff}.next-tag-group .next-tag-large,.next-tag-group .next-tag-medium{margin-right:8px;margin-bottom:8px}.next-tag-group .next-tag-small{margin-right:4px;margin-bottom:4px}.next-tag{display:inline-block;max-width:100%;vertical-align:middle;border-width:1px;border-radius:3px;box-shadow:none;border-style:solid;overflow:hidden;white-space:nowrap;transition:all .1s linear;font-size:0;outline:0}.next-tag,.next-tag *,.next-tag :after,.next-tag :before{box-sizing:border-box}.next-tag>.next-tag-body{position:relative;display:inline-block;height:100%;text-align:center;vertical-align:middle;max-width:100%;cursor:default}.next-tag>.next-tag-body>a{text-decoration:none;color:inherit}.next-tag>.next-tag-body>a:before{content:" ";position:absolute;display:block;top:0;left:0;right:0;bottom:0}.next-tag>.next-tag-body .next-icon{line-height:1;vertical-align:baseline}.next-tag>.next-tag-body .next-icon:before{font-size:inherit}.next-tag.next-tag-body-pointer{cursor:pointer}.next-tag.disabled,.next-tag[disabled]{cursor:not-allowed;pointer-events:none}.next-tag-blue{background-color:#4494f9;border-color:#4494f9;color:#fff}.next-tag-blue-inverse{background-color:rgba(68,148,249,.25);border-color:#4494f9;color:#4494f9}.next-tag-green{background-color:#46bc15;border-color:#46bc15;color:#fff}.next-tag-green-inverse{background-color:rgba(70,188,21,.25);border-color:#46bc15;color:#46bc15}.next-tag-orange{background-color:#ff9300;border-color:#ff9300;color:#fff}.next-tag-orange-inverse{background-color:rgba(255,147,0,.25);border-color:#ff9300;color:#ff9300}.next-tag-red{background-color:#ff3000;border-color:#ff3000;color:#fff}.next-tag-red-inverse{background-color:rgba(255,48,0,.25);border-color:#ff3000;color:#ff3000}.next-tag-turquoise{background-color:#01c1b2;border-color:#01c1b2;color:#fff}.next-tag-turquoise-inverse{background-color:rgba(1,193,178,.25);border-color:#01c1b2;color:#01c1b2}.next-tag-yellow{background-color:#fccc12;border-color:#fccc12;color:#fff}.next-tag-yellow-inverse{background-color:rgba(252,204,18,.25);border-color:#fccc12;color:#fccc12}.next-tag-large{height:40px;padding:0;line-height:38px;font-size:0}.next-tag-large>.next-tag-body{font-size:16px;padding:0 16px;min-width:48px}.next-tag-large.next-tag-closable>.next-tag-body{padding:0 0 0 16px;max-width:calc(100% - 48px)}.next-tag-large[dir=rtl].next-tag-closable>.next-tag-body{padding:0 16px 0 0}.next-tag-large.next-tag-closable>.next-tag-close-btn{margin-left:16px;padding-right:16px}.next-tag-large.next-tag-closable>.next-tag-close-btn .next-icon .next-icon-remote,.next-tag-large.next-tag-closable>.next-tag-close-btn .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-tag-large[dir=rtl]>.next-tag-close-btn{margin-right:16px;margin-left:0;padding-right:0;padding-left:16px}.next-tag-medium{height:32px;padding:0;line-height:30px;font-size:0}.next-tag-medium>.next-tag-body{font-size:14px;padding:0 12px;min-width:40px}.next-tag-medium.next-tag-closable>.next-tag-body{padding:0 0 0 12px;max-width:calc(100% - 36px)}.next-tag-medium[dir=rtl].next-tag-closable>.next-tag-body{padding:0 12px 0 0}.next-tag-medium.next-tag-closable>.next-tag-close-btn{margin-left:12px;padding-right:12px}.next-tag-medium.next-tag-closable>.next-tag-close-btn .next-icon .next-icon-remote,.next-tag-medium.next-tag-closable>.next-tag-close-btn .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-tag-medium[dir=rtl]>.next-tag-close-btn{margin-right:12px;margin-left:0;padding-right:0;padding-left:12px}.next-tag-small{height:24px;padding:0;line-height:22px;font-size:0}.next-tag-small>.next-tag-body{font-size:12px;padding:0 8px;min-width:28px}.next-tag-small.next-tag-closable>.next-tag-body{padding:0 0 0 8px;max-width:calc(100% - 24px)}.next-tag-small[dir=rtl].next-tag-closable>.next-tag-body{padding:0 8px 0 0}.next-tag-small.next-tag-closable>.next-tag-close-btn{margin-left:8px;padding-right:8px}.next-tag-small.next-tag-closable>.next-tag-close-btn .next-icon .next-icon-remote,.next-tag-small.next-tag-closable>.next-tag-close-btn .next-icon:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-tag-small.next-tag-closable>.next-tag-close-btn .next-icon{transform:scale(.5);margin-left:-4px;margin-right:-4px}.next-tag-small.next-tag-closable>.next-tag-close-btn .next-icon:before{width:16px;font-size:16px}}.next-tag-small[dir=rtl]>.next-tag-close-btn{margin-right:8px;margin-left:0;padding-right:0;padding-left:8px}.next-tag-default{cursor:default}.next-tag-closable{position:relative}.next-tag-closable>.next-tag-close-btn{display:inline-block;vertical-align:middle;height:100%;text-align:center;cursor:pointer}.next-tag-checkable{cursor:pointer;position:relative;border-radius:3px}.next-tag-checkable.checked:before{animation:fadeInRightForTag .4s cubic-bezier(.78,.14,.15,.86)}.next-tag-checkable.checked:after{animation:zoomIn .4s cubic-bezier(.78,.14,.15,.86)}.next-tag-checkable.next-tag-small:not(.next-tag-level-primary):before{right:-10px;bottom:-10px;width:20px;height:20px}.next-tag-checkable.next-tag-small:not(.next-tag-level-primary):after{font-size:8px;line-height:8px;right:0;bottom:0}.next-tag-checkable.next-tag-medium:not(.next-tag-level-primary):before{right:-14px;bottom:-14px;width:28px;height:28px}.next-tag-checkable.next-tag-medium:not(.next-tag-level-primary):after{font-size:12px;line-height:12px;right:0;bottom:0}.next-tag-checkable.next-tag-large:not(.next-tag-level-primary):before{right:-18px;bottom:-18px;width:36px;height:36px}.next-tag-checkable.next-tag-large:not(.next-tag-level-primary):after{font-size:16px;line-height:16px;right:0;bottom:0}.next-tag-checkable.next-tag-level-secondary.disabled,.next-tag-checkable.next-tag-level-secondary[disabled]{color:#ccc;border-color:#eee;background-color:#fafafa}.next-tag-zoom-appear,.next-tag-zoom-enter{animation:fadeInLeft .4s cubic-bezier(.78,.14,.15,.86);animation-fill-mode:both}.next-tag-zoom-leave{animation:zoomOut .3s ease-in;animation-fill-mode:both}.next-timeline,.next-timeline *,.next-timeline:after,.next-timeline :after,.next-timeline:before,.next-timeline :before{box-sizing:border-box}.next-timeline ul{margin:0;padding:0;list-style:none}.next-timeline p{margin:0}.next-timeline-hide{display:none}.next-timeline[dir=rtl] .next-timeline-item-folder{padding-left:0;padding-right:28px}.next-timeline[dir=rtl] .next-timeline-item-dot-tail{left:auto;right:8px;border-left:none;border-right:1px dotted #e6e6e6}.next-timeline[dir=rtl] .next-timeline-item-has-left-content.next-timeline-item-folder{margin-left:0;margin-right:80px}.next-timeline[dir=rtl] .next-timeline-item-done{position:relative}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline{position:absolute;left:auto;right:0;top:0;height:100%}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:right}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-right:-12px;margin-left:0;line-height:1}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:auto;right:8px}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-content{display:inline-block;margin-right:28px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:left;padding-left:12px;padding-right:0}.next-timeline[dir=rtl] .next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline[dir=rtl] .next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-right:80px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-content{margin-right:108px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-dot{background:#ddd}.next-timeline[dir=rtl] .next-timeline-item-done .next-timeline-item-icon{background:#ddd;color:#fff}.next-timeline[dir=rtl] .next-timeline-item-process{position:relative}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline{position:absolute;left:auto;right:0;top:0;height:100%}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:right}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-right:-12px;margin-left:0;line-height:1}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:auto;right:8px}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-content{display:inline-block;margin-right:28px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:left;padding-left:12px;padding-right:0}.next-timeline[dir=rtl] .next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline[dir=rtl] .next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-right:80px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-content{margin-right:108px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-dot{background:#209bfa}.next-timeline[dir=rtl] .next-timeline-item-process .next-timeline-item-icon{background:#209bfa;color:#fff}.next-timeline[dir=rtl] .next-timeline-item-success{position:relative}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline{position:absolute;left:auto;right:0;top:0;height:100%}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:right}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-right:-12px;margin-left:0;line-height:1}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:auto;right:8px}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-content{display:inline-block;margin-right:28px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:left;padding-left:12px;padding-right:0}.next-timeline[dir=rtl] .next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline[dir=rtl] .next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-right:80px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-content{margin-right:108px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-dot{background:#1ad78c}.next-timeline[dir=rtl] .next-timeline-item-success .next-timeline-item-icon{background:#1ad78c;color:#fff}.next-timeline[dir=rtl] .next-timeline-item-error{position:relative}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline{position:absolute;left:auto;right:0;top:0;height:100%}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:right}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-right:-12px;margin-left:0;line-height:1}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:auto;right:8px}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-content{display:inline-block;margin-right:28px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:right}.next-timeline[dir=rtl] .next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:left;padding-left:12px;padding-right:0}.next-timeline[dir=rtl] .next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline[dir=rtl] .next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-right:80px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-content{margin-right:108px;margin-left:0}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-dot{background:#d23c26}.next-timeline[dir=rtl] .next-timeline-item-error .next-timeline-item-icon{background:#d23c26;color:#fff}.next-timeline{margin:0;padding:0;list-style:none}.next-timeline>li{outline:0}.next-timeline-item-folder{padding-left:28px;padding-top:4px;padding-bottom:4px;font-size:12px;line-height:1.5;position:relative}.next-timeline-item-dot-tail{position:absolute;top:0;left:8px;height:100%;border:0;border-left:1px dotted #e6e6e6}.next-timeline-item-dot-tail-solid{border-style:solid}.next-timeline-item-has-left-content.next-timeline-item-folder{margin-left:80px}.next-timeline-item-done{position:relative}.next-timeline-item-done .next-timeline-item-timeline{position:absolute;left:0;top:0;height:100%}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:left}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-left:-12px;line-height:1}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:8px}.next-timeline-item-done .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline-item-done .next-timeline-item-content{display:inline-block;margin-left:28px}.next-timeline-item-done .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:left}.next-timeline-item-done .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:left}.next-timeline-item-done .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:left}.next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:right;padding-right:12px}.next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-left:80px}.next-timeline-item-done.next-timeline-item-has-left-content>.next-timeline-item-content{margin-left:108px}.next-timeline-item-done .next-timeline-item-dot{background:#ddd}.next-timeline-item-done .next-timeline-item-icon{background:#ddd;color:#fff}.next-timeline-item-process{position:relative}.next-timeline-item-process .next-timeline-item-timeline{position:absolute;left:0;top:0;height:100%}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:left}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-left:-12px;line-height:1}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:8px}.next-timeline-item-process .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline-item-process .next-timeline-item-content{display:inline-block;margin-left:28px}.next-timeline-item-process .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:left}.next-timeline-item-process .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:left}.next-timeline-item-process .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:left}.next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:right;padding-right:12px}.next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-left:80px}.next-timeline-item-process.next-timeline-item-has-left-content>.next-timeline-item-content{margin-left:108px}.next-timeline-item-process .next-timeline-item-dot{background:#209bfa}.next-timeline-item-process .next-timeline-item-icon{background:#209bfa;color:#fff}.next-timeline-item-success{position:relative}.next-timeline-item-success .next-timeline-item-timeline{position:absolute;left:0;top:0;height:100%}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:left}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-left:-12px;line-height:1}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:8px}.next-timeline-item-success .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline-item-success .next-timeline-item-content{display:inline-block;margin-left:28px}.next-timeline-item-success .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:left}.next-timeline-item-success .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:left}.next-timeline-item-success .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:left}.next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:right;padding-right:12px}.next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-left:80px}.next-timeline-item-success.next-timeline-item-has-left-content>.next-timeline-item-content{margin-left:108px}.next-timeline-item-success .next-timeline-item-dot{background:#1ad78c}.next-timeline-item-success .next-timeline-item-icon{background:#1ad78c;color:#fff}.next-timeline-item-error{position:relative}.next-timeline-item-error .next-timeline-item-timeline{position:absolute;left:0;top:0;height:100%}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-node{position:relative;width:16px;height:24px;padding:4px 0;text-align:center;float:left}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-node.next-timeline-item-node-custom{width:40px;height:auto;font-size:12px;word-break:break-all;margin-left:-12px;line-height:1}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-dot{display:block;position:absolute;width:8px;height:8px;border-radius:100%;top:50%;margin-top:-4px;left:50%;margin-left:-4px}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-icon{display:block;position:absolute;width:16px;height:16px;line-height:16px;border-radius:100%;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-icon .next-icon .next-icon-remote,.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-icon .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-tail{position:absolute;width:auto;height:calc(100% - 24px);top:24px;left:8px}.next-timeline-item-error .next-timeline-item-timeline .next-timeline-item-tail i{display:inline-block;vertical-align:top;height:100%;width:1px;position:relative;background:#e6e6e6;-webkit-transition:all .1s linear;transition:all .1s linear}.next-timeline-item-error .next-timeline-item-content{display:inline-block;margin-left:28px}.next-timeline-item-error .next-timeline-item-content .next-timeline-item-title{font-size:14px;font-weight:700;line-height:1.5;margin:4px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:left}.next-timeline-item-error .next-timeline-item-content .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:left}.next-timeline-item-error .next-timeline-item-content .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:left}.next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-left-content{position:absolute;width:80px;display:inline-block;font-size:12px;color:#999;line-height:1.5;margin-top:4px;text-align:right;padding-right:12px}.next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-left-content p{word-break:break-word}.next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-timeline{margin-left:80px}.next-timeline-item-error.next-timeline-item-has-left-content>.next-timeline-item-content{margin-left:108px}.next-timeline-item-error .next-timeline-item-dot{background:#d23c26}.next-timeline-item-error .next-timeline-item-icon{background:#d23c26;color:#fff}.next-timeline.next-alternate .next-timeline-item-left .next-timeline-item-left-content,.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-left-content{width:50%;padding-right:12px}.next-timeline.next-alternate .next-timeline-item-left .next-timeline-item-timeline,.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-timeline{margin-left:50%}.next-timeline.next-alternate .next-timeline-item-left .next-timeline-item-content,.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-content{margin-left:calc(50% + 28px)}.next-timeline.next-alternate .next-timeline-item-folder{margin-left:50%}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-title{margin:4px 0 0;font-size:14px;font-weight:700;line-height:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:right}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-body{margin:4px 0 0;font-size:12px;line-height:1.5;color:#666;text-align:right}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:right}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-left-content{display:inline-block;position:relative}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-left-content .next-timeline-item-title{margin-top:0}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-content{margin-left:28px;position:absolute}.next-timeline.next-alternate .next-timeline-item-right .next-timeline-item-content .next-timeline-item-body{margin-top:4px;color:#999}.next-timeline[dir=rtl].next-alternate .next-timeline-item-left .next-timeline-item-left-content,.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-left-content{width:50%;padding-left:12px}.next-timeline[dir=rtl].next-alternate .next-timeline-item-left .next-timeline-item-timeline,.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-timeline{margin-right:50%}.next-timeline[dir=rtl].next-alternate .next-timeline-item-left .next-timeline-item-content,.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-content{width:50%;margin-right:calc(50% + 28px)}.next-timeline[dir=rtl].next-alternate .next-timeline-item-folder{margin-right:50%}.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-title{margin:0;font-size:14px;font-weight:700;line-height:1.5;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#333;text-align:left}.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-body{margin:0;font-size:12px;line-height:1.5;color:#666;text-align:left}.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-time{margin:4px 0 12px;font-size:12px;color:#999;text-align:left}.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-left-content{display:inline-block;position:relative}.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-content{margin-right:28px;position:absolute}.next-timeline[dir=rtl].next-alternate .next-timeline-item-right .next-timeline-item-content .next-timeline-item-body{text-align:right}.next-timeline-item-last .next-timeline-item-tail{display:none}.next-timeline-item-has-left-content{min-height:48px}.next-timeline-item-folder.next-timeline-item-has-left-content{min-height:auto}.next-transfer{display:inline-block}.next-transfer,.next-transfer *,.next-transfer :after,.next-transfer :before{box-sizing:border-box}.next-transfer-panel{display:inline-block;border:1px solid #e6e6e6;border-radius:3px;background-color:#fff;vertical-align:middle}.next-transfer-panel-header{padding:8px 20px;border-bottom:1px solid #e6e6e6;background-color:#fafafa;color:#333;font-size:14px}.next-transfer-panel-search{padding:0 4px;margin-top:8px;margin-bottom:0;width:180px}.next-transfer .next-transfer-panel-list{width:180px;height:160px;padding:0;border:none;box-shadow:none;border-radius:0;overflow-y:auto}.next-transfer-panel-not-found-container{display:table;width:100%;height:100%}.next-transfer-panel-not-found{display:table-cell;vertical-align:middle;text-align:center;color:#999;font-size:14px}.next-transfer-panel-item.next-focused{transition:background-color .1s linear}.next-transfer-panel-item:not(.next-disabled).next-simple:hover{color:#209bfa}.next-transfer-panel-item.next-insert-before:before{position:absolute;top:0;left:0;content:"";width:100%;border-top:1px solid #209bfa}.next-transfer-panel-item.next-insert-after:after{position:absolute;left:0;bottom:0;content:"";width:100%;border-bottom:1px solid #209bfa}.next-transfer-panel-footer{position:relative;padding:8px 20px;border-top:1px solid #e6e6e6;background-color:#fff;font-size:0;box-shadow:none}.next-transfer-panel-count{margin-left:4px;font-size:14px;vertical-align:middle;color:#333}.next-transfer-panel-move-all{font-size:14px;color:#209bfa;cursor:pointer}.next-transfer-panel-move-all.next-disabled{color:#ccc;cursor:not-allowed}.next-transfer-operations{display:inline-block;vertical-align:middle;margin:0 20px}.next-transfer-move.next-icon{color:#ddd}.next-transfer-move.next-icon:before{content:""}.next-transfer-operation.next-btn{display:block}.next-transfer-operation.next-btn+.next-transfer-operation.next-btn{margin-top:8px}.next-transfer-operation.next-btn .next-icon .next-icon-remote,.next-transfer-operation.next-btn .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-tree,.next-tree *,.next-tree :after,.next-tree :before{box-sizing:border-box}.next-tree,.next-tree-child-tree{margin:0;padding:0;list-style:none}.next-tree-node{white-space:nowrap}.next-tree-node-inner{font-size:0;outline:none}.next-tree-node-label-wrapper{font-size:0;outline:none;display:inline-block;margin:0 4px;vertical-align:middle}.next-tree-node-label{height:20px;line-height:20px;padding:0 4px;border-radius:3px;font-size:14px}.next-tree-node-label .next-icon{font-size:16px}.next-tree-node-label .next-icon:before{font-size:14px;width:14px;margin-right:.5em}.next-tree-node-input.next-input{margin:0 4px}.next-tree-node-indent-unit{display:inline-block;width:24px;vertical-align:middle;position:relative}.next-tree-node-indent-unit.next-line:before{content:"";position:absolute;display:inline-block;border-left:1px solid #ddd;height:28px;left:7.5px}.next-tree-switcher{position:relative;display:inline-block;vertical-align:middle;margin-right:8px}.next-tree .next-tree-unfold-icon:before{content:""}.next-tree-switcher.next-noline{width:20px;height:20px;line-height:20px;cursor:pointer}.next-tree-switcher.next-noline .next-tree-switcher-icon{transition:transform .1s linear;color:#999}.next-tree-switcher.next-noline .next-tree-switcher-icon .next-icon-remote,.next-tree-switcher.next-noline .next-tree-switcher-icon:before{width:20px;font-size:20px;line-height:inherit}.next-tree-switcher.next-noline .next-tree-fold-icon:before{content:""}.next-tree-switcher.next-noline.next-close .next-tree-switcher-icon{transform:rotate(-90deg)}.next-tree-switcher.next-noline.next-close .next-tree-switcher-icon .next-icon-remote,.next-tree-switcher.next-noline.next-close .next-tree-switcher-icon:before{width:20px;font-size:20px;line-height:inherit}.next-tree-switcher.next-noline:not(.next-disabled):hover .next-tree-switcher-icon{color:#333}.next-tree-switcher.next-noline.next-disabled{cursor:not-allowed}.next-tree-switcher.next-noline.next-disabled .next-tree-switcher-icon{color:#ccc}.next-tree-switcher.next-noop-noline{width:20px;height:20px}.next-tree-switcher.next-line{width:16px;height:16px;line-height:14px;border:1px solid #ddd;border-radius:3px;background-color:#fff;cursor:pointer}.next-tree-switcher.next-line .next-tree-switcher-icon{margin-left:3px;color:#666}.next-tree-switcher.next-line .next-tree-switcher-icon .next-icon-remote,.next-tree-switcher.next-line .next-tree-switcher-icon:before{width:8px;font-size:8px;line-height:inherit}@media (-webkit-min-device-pixel-ratio:0)and (min-resolution:0.001dpcm){.next-tree-switcher.next-line .next-tree-switcher-icon{transform:scale(.5);margin-left:-1px;margin-right:-4px}.next-tree-switcher.next-line .next-tree-switcher-icon:before{width:16px;font-size:16px}}.next-tree-switcher.next-line .next-tree-switcher-fold-icon:before{content:""}.next-tree-switcher.next-line .next-tree-switcher-unfold-icon:before{content:""}.next-tree-switcher.next-line:not(.next-disabled):hover{border-color:#ccc;background-color:#f9f9f9}.next-tree-switcher.next-line:not(.next-disabled):hover .next-tree-switcher-icon{color:#333}.next-tree-switcher.next-line.next-disabled{border-color:#eee;background-color:#fff;cursor:not-allowed}.next-tree-switcher.next-line.next-disabled .next-tree-switcher-icon{color:#ccc}.next-tree-switcher.next-noop-line{width:16px;height:16px}.next-tree-switcher.next-noop-line-noroot{height:0;border-left:1px solid #ddd;border-bottom:1px solid #ddd}.next-tree-switcher.next-noop-line-noroot .next-tree-right-angle{bottom:-1px}.next-tree-switcher.next-loading.next-loading-noline{width:20px;height:20px;line-height:20px}.next-tree-switcher.next-loading.next-loading-line{width:16px;height:16px;line-height:14px;border:1px solid transparent}.next-tree-switcher.next-loading .next-tree-switcher-icon{color:#209bfa}.next-tree-switcher.next-loading .next-tree-switcher-icon .next-icon-remote,.next-tree-switcher.next-loading .next-tree-switcher-icon:before{width:20px;font-size:20px;line-height:inherit}.next-tree-right-angle{position:absolute;bottom:6.5px;left:-17.5px;display:block;width:16.5px;height:22px;border-left:1px solid #ddd;border-bottom:1px solid #ddd}.next-tree.next-label-block .next-tree-node-inner{display:flex;align-items:center}.next-tree.next-label-block .next-tree-node-label-wrapper{flex:1 1 auto;outline:none}.next-tree.next-node-indent .next-tree-node .next-tree-node{margin-left:24px}.next-tree.next-node-indent .next-tree-node-inner{padding-top:2px;padding-bottom:2px}.next-tree.next-node-indent .next-tree-node-label-wrapper{border-top:2px solid transparent;border-bottom:2px solid transparent}.next-tree.next-node-indent .next-tree-node-label-wrapper:focus .next-tree-node-label{color:#333;background-color:#f9f9f9}.next-tree.next-node-indent .next-tree-node-label{transition:color .1s linear,background-color .1s linear;cursor:default;color:#333;background-color:#fff}.next-tree.next-node-indent .next-tree-node-label-selectable{cursor:pointer}.next-tree.next-node-indent .next-tree-node-label:hover{color:#333;background-color:#f9f9f9}.next-tree.next-node-indent .next-tree-node-inner.next-selected .next-tree-node-label{color:#333;background-color:#add9ff}.next-tree.next-node-indent .next-tree-node-inner.next-disabled .next-tree-node-label,.next-tree.next-node-indent .next-tree-node-inner.next-disabled .next-tree-node-label:hover{color:#ccc;background-color:#fff;cursor:not-allowed}.next-tree.next-node-indent .next-tree-node-inner.next-drag-over .next-tree-node-label{background-color:#209bfa;color:#fff;opacity:.8}.next-tree.next-node-indent .next-tree-node-inner.next-drag-over-gap-top .next-tree-node-label-wrapper{border-top-color:#209bfa}.next-tree.next-node-indent .next-tree-node-inner.next-drag-over-gap-bottom .next-tree-node-label-wrapper{border-bottom-color:#209bfa}.next-tree.next-node-block .next-tree-node-inner{padding-top:4px;padding-bottom:4px;transition:color .1s linear,background-color .1s linear;display:flex;align-items:center}.next-tree.next-node-block .next-tree-node-inner .next-tree-node-label-wrapper{cursor:pointer;flex-grow:1;color:#333;background-color:#fff}.next-tree.next-node-block .next-tree-node-inner .next-tree-node-label-wrapper:focus,.next-tree.next-node-block .next-tree-node-inner .next-tree-node-label-wrapper:hover{color:#333;background-color:#f9f9f9}.next-tree.next-node-block .next-tree-node-inner.next-selected .next-tree-node-label{color:#333;background-color:#add9ff}.next-tree.next-node-block .next-tree-node-inner.next-disabled .next-tree-node-label,.next-tree.next-node-block .next-tree-node-inner.next-disabled:hover .next-tree-node-label{color:#ccc;background-color:#fff;cursor:not-allowed}.next-tree.next-show-line .next-tree-node .next-tree-node:not(:last-child){margin-left:7.5px;border-left:1px solid #ddd;padding-left:15.5px}.next-tree-node.next-filtered>.next-tree-node-inner .next-tree-node-label,.next-tree-node.next-filtered>.next-tree-node-inner .next-tree-node-label:hover{color:#209bfa}.next-tree[dir=rtl] .next-tree-switcher{margin-left:8px;margin-right:0}.next-tree[dir=rtl] .next-tree-right-angle,.next-tree[dir=rtl] .next-tree-switcher.next-noop-line-noroot{border-left:none;border-right:1px solid #ddd}.next-tree[dir=rtl] .next-tree-right-angle{left:auto;right:-17.5px}.next-tree[dir=rtl].next-show-line .next-tree-node .next-tree-node:not(:last-child){margin-left:0;margin-right:7.5px;border-left:none;border-right:1px solid #ddd;padding-left:0;padding-right:15.5px}.next-tree[dir=rtl].next-node-indent .next-tree-node .next-tree-node{margin-left:0;margin-right:24px}.next-tree-select,.next-tree-select *,.next-tree-select :after,.next-tree-select :before{box-sizing:border-box}.next-tree-select-dropdown{background:#fff;border:1px solid #e6e6e6;border-radius:3px;box-shadow:none;max-height:260px;overflow:auto}.next-tree-select-dropdown>.next-tree,.next-tree-select-dropdown>.next-tree-select-not-found,.next-tree-select-dropdown>.next-virtual-tree-container{padding:8px 20px}.next-tree-select-not-found{font-size:14px;color:#999}.next-upload-list[dir=rtl].next-upload-list-text .next-upload-list-item{padding:4px 8px 4px 40px}.next-upload-list[dir=rtl].next-upload-list-text .next-icon{left:12px;right:auto}.next-upload-list[dir=rtl].next-upload-list-image .next-icon-close{float:left;margin-left:4px;margin-right:0}.next-upload-list[dir=rtl].next-upload-list-image .next-upload-list-item-thumbnail{float:right;margin-left:8px;margin-right:0}.next-upload-list[dir=rtl].next-upload-list-image .next-upload-list-item-progress{margin-right:56px;margin-left:24px}.next-upload,.next-upload *,.next-upload :after,.next-upload :before{box-sizing:border-box}.next-upload-inner{outline:0;display:inline-block}.next-upload-inner.next-hidden{display:none}.next-upload-list{overflow:hidden}.next-upload-list,.next-upload-list *,.next-upload-list :after,.next-upload-list :before{box-sizing:border-box}.next-upload-list-item{position:relative}.next-upload-list-item.next-hidden{display:none}.next-upload-list-item-name{text-decoration:none}.next-upload.next-disabled{border-color:#eee!important;color:#ccc!important}.next-upload.next-disabled .next-icon-close{cursor:not-allowed!important}.next-upload.next-disabled .next-upload-inner *{color:#ccc!important;border-color:#eee!important;cursor:not-allowed!important}.next-upload-list-text .next-upload-list-item{background-color:#f9f9f9;padding:4px 40px 4px 8px;height:40px;line-height:32px;font-size:14px;overflow:hidden;transition:all .1s linear;border-radius:0}.next-upload-list-text .next-upload-list-item:not(:last-child){margin-bottom:4px}.next-upload-list-text .next-upload-list-item-op{position:absolute;top:0;right:12px}.next-upload-list-text .next-upload-list-item .next-icon-close{color:#999;cursor:pointer;text-align:center;transition:all .1s linear;line-height:40px}.next-upload-list-text .next-upload-list-item .next-icon-close .next-icon-remote,.next-upload-list-text .next-upload-list-item .next-icon-close:before{width:16px;font-size:16px;line-height:inherit}.next-upload-list-text .next-upload-list-item:hover{background-color:#f9f9f9}.next-upload-list-text .next-upload-list-item:hover .next-icon{color:#666}.next-upload-list-text .next-upload-list-item-name-wrap{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;margin-right:4px}.next-upload-list-text .next-upload-list-item-name{color:#333;transition:all .1s linear}.next-upload-list-text .next-upload-list-item-size{color:#999;margin-left:8px}.next-upload-list-text .next-upload-list-item-uploading{line-height:16px}.next-upload-list-text .next-upload-list-item-uploading .next-upload-list-item-progress{line-height:0;padding-top:4px;padding-bottom:4px}.next-upload-list-text .next-upload-list-item-uploading .next-upload-list-item-progress .next-progress-line-underlay{height:8px}.next-upload-list-text .next-upload-list-item-uploading .next-upload-list-item-progress .next-progress-line-overlay{height:8px;margin-top:-4px}.next-upload-list-text .next-upload-list-item-done{line-height:32px}.next-upload-list-text .next-upload-list-item-done:hover .next-upload-list-item-name,.next-upload-list-text .next-upload-list-item-done:hover .next-upload-list-item-size{color:#209bfa}.next-upload-list-text .next-upload-list-item-error{background-color:#ffece4!important}.next-upload-list-text .next-upload-list-item-error.next-upload-list-item-error-with-msg{line-height:16px}.next-upload-list-text .next-upload-list-item-error-msg{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;color:#d23c26}.next-upload-list-image .next-upload-list-item{box-sizing:content-box;border:1px solid #e6e6e6;background-color:#fff;padding:8px;height:48px;line-height:48px;font-size:14px;transition:all .1s linear;overflow:hidden;border-radius:0}.next-upload-list-image .next-upload-list-item:not(:last-child){margin-bottom:4px}.next-upload-list-image .next-upload-list-item:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-upload-list-image .next-upload-list-item-op{float:right;margin-right:4px}.next-upload-list-image .next-upload-list-item .next-icon-close{cursor:pointer;color:#999;text-align:center}.next-upload-list-image .next-upload-list-item .next-icon-close .next-icon-remote,.next-upload-list-image .next-upload-list-item .next-icon-close:before{width:16px;font-size:16px;line-height:inherit}.next-upload-list-image .next-upload-list-item:hover{border-color:#209bfa}.next-upload-list-image .next-upload-list-item:hover .next-icon-close{color:#666}.next-upload-list-image .next-upload-list-item-name{display:block;color:#333;margin-left:56px;margin-right:24px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;transition:all .1s linear}.next-upload-list-image .next-upload-list-item-size{color:#999;margin-left:8px}.next-upload-list-image .next-upload-list-item-done:hover .next-upload-list-item-name,.next-upload-list-image .next-upload-list-item-done:hover .next-upload-list-item-size{color:#209bfa}.next-upload-list-image .next-upload-list-item-thumbnail{float:left;width:48px;height:48px;color:#ccc;border:1px solid #e6e6e6;border-radius:0;background-color:#f9f9f9;margin-right:8px;vertical-align:middle;text-align:center;overflow:hidden;box-sizing:border-box}.next-upload-list-image .next-upload-list-item-thumbnail img{width:100%;height:100%}.next-upload-list-image .next-upload-list-item-thumbnail .next-icon{display:block;margin:0;line-height:48px}.next-upload-list-image .next-upload-list-item-thumbnail .next-icon .next-icon-remote,.next-upload-list-image .next-upload-list-item-thumbnail .next-icon:before{width:24px;font-size:24px;line-height:inherit}.next-upload-list-image .next-upload-list-item-error{border-color:#d23c26!important;background-color:#fff}.next-upload-list-image .next-upload-list-item-uploading{background-color:#fff}.next-upload-list-image .next-upload-list-item-uploading .next-upload-list-item-name{height:24px;line-height:24px}.next-upload-list-image .next-upload-list-item-uploading .next-upload-list-item-progress{margin-left:56px;margin-right:24px;line-height:0;padding-top:8px;padding-bottom:8px}.next-upload-list-image .next-upload-list-item-uploading .next-upload-list-item-progress .next-progress-line-underlay{height:8px}.next-upload-list-image .next-upload-list-item-uploading .next-upload-list-item-progress .next-progress-line-overlay{height:8px;margin-top:-4px}.next-upload-list-image .next-upload-list-item-error-with-msg .next-upload-list-item-error-msg,.next-upload-list-image .next-upload-list-item-error-with-msg .next-upload-list-item-name{height:24px;line-height:24px}.next-upload-list-image .next-upload-list-item-error-with-msg .next-upload-list-item-error-msg{margin-left:56px;margin-right:24px;color:#d23c26;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.next-upload-list-card{display:inline-block}.next-upload-list-card .next-upload-list-item{vertical-align:middle;float:left}.next-upload-list-card .next-upload-list-item:not(:last-child){margin-right:12px}.next-upload-list-card .next-upload-list-item-wrapper{position:relative;border:1px solid #ddd;width:100px;height:100px;padding:0;background-color:transparent;border-radius:0;overflow:hidden}.next-upload-list-card .next-upload-list-item-thumbnail{text-align:center;width:100%;height:100%;color:#ccc;font-size:12px}.next-upload-list-card .next-upload-list-item-thumbnail img{max-width:100%;max-height:100%;position:absolute;top:0;right:0;bottom:0;left:0;margin:auto}.next-upload-list-card .next-upload-list-item-thumbnail img:focus{outline:0}.next-upload-list-card .next-upload-list-item-thumbnail .next-icon{width:100%}.next-upload-list-card .next-upload-list-item-thumbnail .next-icon .next-icon-remote,.next-upload-list-card .next-upload-list-item-thumbnail .next-icon:before{width:48px;font-size:48px;line-height:inherit}.next-upload-list-card .next-upload-list-item-handler{margin-top:13px}.next-upload-list-card .next-upload-list-item-handler .next-icon-cry{margin-top:10px}.next-upload-list-card .next-upload-list-item-name{display:block;width:100px;text-align:center;margin-top:4px;font-size:12px;color:#666;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.next-upload-list-card .next-upload-list-item-progress{position:absolute;font-size:0;bottom:0;left:0;width:100%}.next-upload-list-card .next-upload-list-item-progress .next-progress-line-underlay{border-radius:0;height:8px}.next-upload-list-card .next-upload-list-item-progress .next-progress-line-overlay{border-radius:0;height:8px;margin-top:-4px}.next-upload-list-card .next-upload-list-item-uploading .next-upload-list-item-wrapper{background-color:#fafafa}.next-upload-list-card .next-upload-list-item:hover .next-upload-tool{opacity:.8}.next-upload-list-card .next-upload-list-item .next-upload-tool{position:absolute;z-index:1;background-color:rgba(0,0,0,.7);transition:all .1s linear;opacity:0;width:100%;height:28px;left:0;bottom:0;display:flex}.next-upload-list-card .next-upload-list-item .next-upload-tool .next-icon{line-height:28px;color:#fff;cursor:pointer}.next-upload-list-card .next-upload-list-item .next-upload-tool .next-icon .next-icon-remote,.next-upload-list-card .next-upload-list-item .next-upload-tool .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-upload-list-card .next-upload-list-item .next-upload-tool-item{width:100%;text-align:center}.next-upload-list-card .next-upload-list-item .next-upload-tool-item:not(:last-child){border-right:1px solid #fff}.next-upload-list-card .next-upload-list-item .next-upload-tool-reupload{display:inline-block}.next-upload-list-card .next-upload-list-item .next-upload-card{display:flex;flex-direction:column;justify-content:center}.next-upload-list-card .next-upload-list-item-error .next-upload-list-item-wrapper{border-color:#d23c26}.next-upload-list-card.next-upload-ie9 .next-upload-tool{display:table}.next-upload-list-card.next-upload-ie9 .next-upload-tool-item{display:table-cell;width:1%}.next-upload-card,.next-upload-list-card.next-upload-ie9 .next-upload-card{display:table-cell}.next-upload-card{border:1px dashed #ddd;width:100px;height:100px;background-color:#fff;text-align:center;cursor:pointer;transition:border-color .1s linear;vertical-align:middle;border-radius:0}.next-upload-card .next-icon{color:#ddd}.next-upload-card .next-icon .next-icon-remote,.next-upload-card .next-icon:before{width:24px;font-size:24px;line-height:inherit}.next-upload-card .next-upload-add-icon:before{content:""}.next-upload-card .next-upload-text{font-size:14px;margin-top:12px;color:#666;outline:none}.next-upload-card:hover{border-color:#209bfa}.next-upload-card:hover .next-icon,.next-upload-card:hover .next-upload-text{color:#209bfa}.next-upload-dragable .next-upload-inner{display:block}.next-upload-dragable .next-upload-drag{border:1px dashed #ddd;transition:border-color .1s linear;cursor:pointer;border-radius:3px;background-color:transparent;text-align:center;margin-bottom:4px}.next-upload-dragable .next-upload-drag-icon{margin:20px 0 0;color:#666}.next-upload-dragable .next-upload-drag-icon .next-upload-drag-upload-icon:before{content:"";font-size:24px}.next-upload-dragable .next-upload-drag-text{margin:12px 0 0;font-size:14px;color:#666}.next-upload-dragable .next-upload-drag-hint{margin:4px 0 20px;font-size:12px;color:#999}.next-upload-dragable .next-upload-drag-over{border-color:#209bfa}.next-shell{position:relative;display:flex;flex-direction:column;transition:all .2s ease}.next-shell,.next-shell *,.next-shell :after,.next-shell :before{box-sizing:border-box}.next-shell-content-wrapper{overflow:auto}.next-shell-header{display:flex;width:100%;justify-content:space-between;align-items:center;z-index:9}.next-shell-header .dock-trigger,.next-shell-header .nav-trigger{outline:0;display:flex;justify-content:center;align-items:center;cursor:pointer;width:32px;height:32px}.next-shell-header .nav-trigger{margin-right:10px}.next-shell-header .dock-trigger{margin-left:10px}.next-shell-header.next-shell-fixed-header{position:sticky;top:0}.next-shell-header .next-shell-navigation{flex:1 1;display:flex;align-items:center;flex-direction:row}.next-shell-header .next-shell-action,.next-shell-header .next-shell-branding{display:flex;align-items:center}.next-shell-sub-main{flex:1 1;flex-direction:column;outline:0}.next-shell-main,.next-shell-sub-main{display:flex;height:100%;overflow:auto}.next-shell-main{flex:1 1 auto;flex-direction:row;position:relative;box-sizing:content-box;transition:all .2s ease}.next-shell-main .next-shell-content{flex:1 1 auto}.next-shell-main .next-shell-content-inner{margin:0 auto}.next-shell-main .next-shell-footer{display:flex;flex-direction:column;justify-content:center;align-items:center;width:100%}.next-shell .next-aside-navigation,.next-shell .next-aside-tooldock{display:flex}.next-shell .next-aside-navigation.fixed,.next-shell .next-aside-tooldock.fixed{position:fixed;top:0;bottom:0;z-index:1}.next-shell .next-aside-navigation.fixed{left:0}.next-shell .next-aside-tooldock.fixed{right:0}.next-shell-aside{transition:all .2s ease}.next-shell-aside .aside-trigger{cursor:pointer;outline:0;position:absolute;right:0;top:50%;width:20px;height:48px;display:flex;border:1px solid #ddd;align-items:center;justify-content:center}.next-shell-aside .local-nav-trigger{outline:0;border-left:none;transform:translate(100%,-50%);right:0}.next-shell-aside .ancillary-trigger{outline:0;transform:translate(-100%,-50%);border-right:0;left:1px}.next-shell-aside.next-aside-ancillary,.next-shell-aside.next-aside-localnavigation{position:relative}.next-shell-aside.next-shell-navigation{display:flex;flex-direction:column;justify-self:flex-start;transition:all .2s ease}.next-shell-aside.next-shell-tooldock{display:flex;flex-direction:column;align-items:center}.next-shell-aside .next-shell-tooldockitem{width:100%;text-align:center}.next-shell-aside .next-shell-localnavigation{position:relative}.next-shell-aside .next-shell-ancillary,.next-shell-aside .next-shell-localnavigation{height:100%;display:flex;flex-direction:column;justify-self:flex-start;transition:all .2s ease}.next-shell-light .next-shell-header .dock-trigger,.next-shell-light .next-shell-header .nav-trigger{background:#fff}.next-shell-light .next-shell-aside .local-nav-trigger{background:#f2f2f2}.next-shell-light .next-shell-aside .ancillary-trigger{background:#fff}.next-shell-light .next-shell-header{color:#000;height:52px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0 16px}.next-shell-light .next-shell-header .next-shell-navigation{justify-content:flex-end;height:52px;line-height:52px;margin:0 48px}.next-shell-light .next-shell-task-header{width:100%;min-height:40px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0;overflow:auto}.next-shell-light .next-shell-main{background:#f5f5f5}.next-shell-light .next-shell-main .next-shell-appbar{min-height:48px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0 24px}.next-shell-light .next-shell-main .next-shell-content{padding:20px}.next-shell-light .next-shell-main .next-shell-footer{background:transparent;min-height:56px;color:#ccc;font-size:14px}.next-shell-light .next-shell-aside.next-shell-navigation{width:200px;background:#fff;border-right:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-light .next-shell-aside.next-shell-navigation.next-shell-collapse.next-shell-mini{width:60px}.next-shell-light .next-shell-aside.next-shell-navigation.next-shell-collapse{width:0}.next-shell-light .next-shell-aside.next-shell-tooldock{width:52px;background:#f2f2f2;border-left:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-light .next-shell-aside .next-shell-tooldockitem{padding:8px 0;color:#666;background:transparent}.next-shell-light .next-shell-aside .next-shell-tooldockitem:hover{color:#333;background:#f5f5f5}.next-shell-light .next-shell-aside .next-shell-localnavigation{width:168px;background:#f2f2f2;border-right:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-light .next-shell-aside .next-shell-localnavigation.next-shell-collapse{width:0}.next-shell-light .next-shell-aside .next-shell-ancillary{width:168px;background:#fff;border-left:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-light .next-shell-aside .next-shell-ancillary.next-shell-collapse{width:0}.next-shell-dark .next-shell-header .dock-trigger,.next-shell-dark .next-shell-header .nav-trigger{background:#222}.next-shell-dark .next-shell-aside .local-nav-trigger{background:#f2f2f2}.next-shell-dark .next-shell-aside .ancillary-trigger{background:#fff}.next-shell-dark .next-shell-header{color:#fff;height:52px;background:#222;border-bottom:1px solid #1f1f1f;box-shadow:0 1px 3px 0 rgba(0,0,0,.12);padding:0 16px}.next-shell-dark .next-shell-header .next-shell-navigation{justify-content:flex-end;height:52px;line-height:52px;margin:0 48px}.next-shell-dark .next-shell-task-header{width:100%;min-height:40px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0;overflow:auto}.next-shell-dark .next-shell-main{background:#f5f5f5}.next-shell-dark .next-shell-main .next-shell-appbar{min-height:48px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0 24px}.next-shell-dark .next-shell-main .next-shell-content{padding:20px}.next-shell-dark .next-shell-main .next-shell-footer{background:transparent;min-height:56px;color:#ccc;font-size:14px}.next-shell-dark .next-shell-aside.next-shell-navigation{width:200px;background:#222;border-right:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-dark .next-shell-aside.next-shell-navigation.next-shell-collapse.next-shell-mini{width:60px}.next-shell-dark .next-shell-aside.next-shell-navigation.next-shell-collapse{width:0}.next-shell-dark .next-shell-aside.next-shell-tooldock{width:52px;background:#f2f2f2;border-left:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-dark .next-shell-aside .next-shell-tooldockitem{padding:8px 0;color:#666;background:transparent}.next-shell-dark .next-shell-aside .next-shell-tooldockitem:hover{color:#333;background:#f5f5f5}.next-shell-dark .next-shell-aside .next-shell-localnavigation{width:168px;background:#f2f2f2;border-right:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-dark .next-shell-aside .next-shell-localnavigation.next-shell-collapse{width:0}.next-shell-dark .next-shell-aside .next-shell-ancillary{width:168px;background:#fff;border-left:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-dark .next-shell-aside .next-shell-ancillary.next-shell-collapse{width:0}.next-shell-brand .next-shell-header .dock-trigger,.next-shell-brand .next-shell-header .nav-trigger{background:#18263c}.next-shell-brand .next-shell-aside .local-nav-trigger{background:#f2f2f2}.next-shell-brand .next-shell-aside .ancillary-trigger{background:#fff}.next-shell-brand .next-shell-header{color:#fff;height:52px;background:#18263c;border-bottom:1px solid #eee;box-shadow:0 1px 3px 0 rgba(0,0,0,.12);padding:0 16px}.next-shell-brand .next-shell-header .next-shell-navigation{justify-content:flex-end;height:52px;line-height:52px;margin:0 48px}.next-shell-brand .next-shell-task-header{width:100%;min-height:40px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0;overflow:auto}.next-shell-brand .next-shell-main{background:#f5f5f5}.next-shell-brand .next-shell-main .next-shell-appbar{min-height:48px;background:#fff;border-bottom:1px solid #eee;box-shadow:none;padding:0 24px}.next-shell-brand .next-shell-main .next-shell-content{padding:20px}.next-shell-brand .next-shell-main .next-shell-footer{background:transparent;min-height:56px;color:#ccc;font-size:14px}.next-shell-brand .next-shell-aside.next-shell-navigation{width:200px;background:#fff;border-right:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-brand .next-shell-aside.next-shell-navigation.next-shell-collapse.next-shell-mini{width:60px}.next-shell-brand .next-shell-aside.next-shell-navigation.next-shell-collapse{width:0}.next-shell-brand .next-shell-aside.next-shell-tooldock{width:52px;background:#f2f2f2;border-left:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-brand .next-shell-aside .next-shell-tooldockitem{padding:8px 0;color:#666;background:transparent}.next-shell-brand .next-shell-aside .next-shell-tooldockitem:hover{color:#333;background:#f5f5f5}.next-shell-brand .next-shell-aside .next-shell-localnavigation{width:168px;background:#f2f2f2;border-right:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-brand .next-shell-aside .next-shell-localnavigation.next-shell-collapse{width:0}.next-shell-brand .next-shell-aside .next-shell-ancillary{width:168px;background:#fff;border-left:1px solid #eee;box-shadow:none;padding:8px 0}.next-shell-brand .next-shell-aside .next-shell-ancillary.next-shell-collapse{width:0}.next-shell-header .next-shell-navigation.next-shell-nav-left{justify-content:flex-start}.next-shell-header .next-shell-navigation.next-shell-nav-right{justify-content:flex-end}.next-shell-header .next-shell-navigation.next-shell-nav-center{justify-content:center}.next-shell.next-shell-phone .next-aside-navigation{width:100%}.next-shell.next-shell-phone .next-aside-navigation.next-shell-collapse{width:0}.next-shell.next-shell-phone .next-shell-header .next-shell-navigation{display:none}.next-shell.next-shell-phone .next-shell-navigation{width:100%;height:100%;transition:height .2s ease}.next-shell.next-shell-phone .next-shell-navigation.next-shell-collapse{padding:0;height:0;transition:height .2s ease}.next-shell.next-shell-phone .next-shell-tooldock{height:52px;left:0;right:0;position:absolute;width:100%;flex-direction:row;justify-content:center}.next-shell.next-shell-phone .next-shell-tooldock.next-shell-collapse{display:none;height:0;padding:0;transition:all .2s ease}.next-shell.next-shell-phone .next-shell-aside.next-aside-ancillary,.next-shell.next-shell-tablet .next-shell-aside.next-aside-ancillary{width:0}.next-shell.next-shell-phone .next-shell-ancillary,.next-shell.next-shell-tablet .next-shell-ancillary{transform:translateX(-100%)}.next-shell.next-shell-phone .next-shell-aside.next-aside-localnavigation,.next-shell.next-shell-tablet .next-shell-aside.next-aside-localnavigation{width:0}.next-notification{width:384px;position:fixed;z-index:1010;padding:0;margin:0}.next-notification .next-message{margin-bottom:16px;overflow:hidden}.next-notification-fade-leave{animation-duration:.3s;animation-play-state:paused;animation-fill-mode:both;animation-timing-function:ease}.next-notification-fade-leave.next-notification-fade-leave-active{animation-name:NotificationFadeOut;animation-play-state:running}@keyframes NotificationFadeOut{0%{max-height:150px;margin-bottom:16px;opacity:1}to{max-height:0;margin-bottom:0;padding-top:0;padding-bottom:0;opacity:0}}.next-typography{color:#333}.next-typography-title{font-weight:600;margin-bottom:.5em}.next-typography+.next-typography-title{margin-top:1.2em}.next-typography-paragraph{color:#333;margin-bottom:1em;font-size:14px;line-height:1.5}.next-typography mark{padding:0;background:#ffe98f;color:#333}.next-typography strong{font-weight:600}.next-typography code{background-color:#f9f9f9;color:#333;border:1px solid #eee;margin:0 .2em;padding:.2em .4em .1em;font-size:85%;border-radius:3px}.next-typography ol,.next-typography ul{margin:0 0 1em;padding:0}.next-typography li{list-style-type:circle;margin:0 0 0 20px;padding:0 0 0 4px}.next-typography a{text-decoration:none}.next-typography a:link{color:#298dff}.next-typography a:visited{color:#4a83c5}.next-typography a:hover{color:#2580e7}.next-typography a:active{text-decoration:underline;color:#2580e7}h1.next-typography-title{font-size:24px}h2.next-typography-title{font-size:20px}h3.next-typography-title,h4.next-typography-title{font-size:16px}.next-divider,h5.next-typography-title,h6.next-typography-title{font-size:14px}.next-divider{margin:0;padding:0;line-height:1.5;list-style:none;font-variant:tabular-nums;font-feature-settings:"tnum";background:#e6e6e6;border-collapse:separate}.next-divider,.next-divider *,.next-divider :after,.next-divider :before{box-sizing:border-box}.next-divider-hoz{display:block;clear:both;width:100%;min-width:100%;height:1px;margin:16px 0}.next-divider-ver{position:relative;top:-.06em;display:inline-block;width:1px;background:#e6e6e6;height:.9em;margin:0 8px;vertical-align:middle}.next-divider-hoz.next-divider-with-text-center,.next-divider-hoz.next-divider-with-text-left,.next-divider-hoz.next-divider-with-text-right{display:table;margin:16px 0;color:#333;font-weight:400;font-size:16px;white-space:nowrap;text-align:center;background:transparent}.next-divider-hoz.next-divider-with-text-center:after,.next-divider-hoz.next-divider-with-text-center:before,.next-divider-hoz.next-divider-with-text-left:after,.next-divider-hoz.next-divider-with-text-left:before,.next-divider-hoz.next-divider-with-text-right:after,.next-divider-hoz.next-divider-with-text-right:before{top:50%;display:table-cell;width:50%;border-top:1px solid #e6e6e6;transform:translateY(50%);content:""}.next-divider-hoz.next-divider-with-text-center.next-divider-dashed,.next-divider-hoz.next-divider-with-text-left.next-divider-dashed,.next-divider-hoz.next-divider-with-text-right.next-divider-dashed{border-top:0}.next-divider-hoz.next-divider-with-text-center.next-divider-dashed:after,.next-divider-hoz.next-divider-with-text-center.next-divider-dashed:before,.next-divider-hoz.next-divider-with-text-left.next-divider-dashed:after,.next-divider-hoz.next-divider-with-text-left.next-divider-dashed:before,.next-divider-hoz.next-divider-with-text-right.next-divider-dashed:after,.next-divider-hoz.next-divider-with-text-right.next-divider-dashed:before{border-style:dashed none none}.next-divider-hoz.next-divider-with-text-left .next-divider-inner-text,.next-divider-hoz.next-divider-with-text-right .next-divider-inner-text{display:inline-block;padding:0 16px}.next-divider-hoz.next-divider-with-text-left:before{top:50%;width:5%}.next-divider-hoz.next-divider-with-text-left:after,.next-divider-hoz.next-divider-with-text-right:before{top:50%;width:95%}.next-divider-hoz.next-divider-with-text-right:after{top:50%;width:5%}.next-divider-inner-text{display:inline-block;padding:0 16px}.next-divider-dashed{background:none;border:dashed #e6e6e6;border-width:1px 0 0}.next-divider-dashed.next-divider-ver{border-width:0 0 0 1px}.next-box{display:flex}.next-box,.next-box *,.next-box :after,.next-box :before,.next-table{box-sizing:border-box}.next-table{position:relative;border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0;border-top:1px solid #e6e6e6;border-left:1px solid #e6e6e6}.next-table *,.next-table :after,.next-table :before{box-sizing:border-box}.next-table .next-table-header tr:first-child th:first-child{border-top-left-radius:0}.next-table .next-table-header tr:first-child th:last-child{border-top-right-radius:0}.next-table .next-table-header tr:last-child th:first-child{border-bottom-left-radius:0}.next-table .next-table-header tr:last-child th:last-child{border-bottom-right-radius:0}.next-table.next-table-layout-fixed{overflow:auto}.next-table.next-table-layout-fixed table{table-layout:fixed}.next-table.next-table-layout-auto table{table-layout:auto}.next-table.next-table-small .next-table-prerow .next-table-cell-wrapper,.next-table.next-table-small td .next-table-cell-wrapper,.next-table.next-table-small th .next-table-cell-wrapper{padding:8px}.next-table table{border-collapse:separate;border-spacing:0;width:100%;background:#fff;border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0}.next-table table tr:first-child td{border-top-width:0}.next-table th{padding:0;background:#f5f5f5;color:#333;text-align:left;font-weight:400;border-right:1px solid #e6e6e6;border-bottom:1px solid #e6e6e6}.next-table th .next-table-cell-wrapper{padding:12px 16px;overflow:hidden;text-overflow:ellipsis;word-break:break-all}.next-table th.next-table-prerow .next-table-cell-wrapper{padding:12px 16px}.next-table th.next-table-word-break-word .next-table-cell-wrapper{word-break:break-word}.next-table th.next-table-fix-left,.next-table th.next-table-fix-right{z-index:1}.next-table-affix{z-index:1;overflow:hidden}.next-table-stickylock .next-table-affix{z-index:9}.next-table-header-resizable{position:relative}.next-table-header-resizable .next-table-resize-handler{position:absolute;right:-5px;top:0;bottom:0;width:10px;background:transparent;cursor:ew-resize}.next-table-header-resizable .next-table-resize-handler:after{position:absolute;display:block;content:" ";width:2px;height:100%;right:50%}.next-table-header-resizable .next-table-resize-handler:hover:after{z-index:1;background:#209bfa}.next-table.next-table-lock-left .next-table-header-resizable .next-table-resize-handler,.next-table.next-table-lock-right .next-table-header-resizable .next-table-resize-handler{cursor:auto}.next-table.next-table-lock-left .next-table-header-resizable .next-table-resize-handler:hover:after,.next-table.next-table-lock-right .next-table-header-resizable .next-table-resize-handler:hover:after{z-index:-1}.next-table td{padding:0;border-right:1px solid #e6e6e6;border-bottom:1px solid #e6e6e6}.next-table td .next-table-cell-wrapper{padding:12px 16px;overflow:hidden;text-overflow:ellipsis;word-break:break-all}.next-table td .next-table-cell-wrapper .next-icon-arrow-down.next-table-tree-arrow,.next-table td .next-table-cell-wrapper .next-icon-arrow-right.next-table-tree-arrow,.next-table td .next-table-cell-wrapper .next-table-tree-placeholder{margin-right:8px;outline:0;cursor:pointer}.next-table td .next-table-cell-wrapper .next-icon-arrow-right.next-table-tree-arrow .next-icon-remote,.next-table td .next-table-cell-wrapper .next-icon-arrow-right.next-table-tree-arrow:before{width:12px;font-size:12px;line-height:inherit}.next-table td .next-table-cell-wrapper .next-icon-arrow-right.next-table-tree-arrow:before{content:""}.next-table td .next-table-cell-wrapper .next-icon-arrow-down.next-table-tree-arrow .next-icon-remote,.next-table td .next-table-cell-wrapper .next-icon-arrow-down.next-table-tree-arrow:before{width:12px;font-size:12px;line-height:inherit}.next-table td .next-table-cell-wrapper .next-icon-arrow-down.next-table-tree-arrow:before{content:""}.next-table td.next-table-prerow .next-table-cell-wrapper{padding:12px 16px}.next-table td.next-table-word-break-word .next-table-cell-wrapper{word-break:break-word}.next-table .next-table-expanded .next-table-cell-wrapper,.next-table .next-table-selection .next-table-cell-wrapper{overflow:visible}.next-table.no-header table tr:first-child td{border-top-width:1px}.next-table.only-bottom-border{border-width:0}.next-table.only-bottom-border td,.next-table.only-bottom-border th{border-width:0 0 1px}.next-table.only-bottom-border table tr td:first-child,.next-table.only-bottom-border table tr th:first-child{border-left-width:0}.next-table.only-bottom-border .next-table-body tr td:last-child,.next-table.only-bottom-border .next-table-header tr th:last-child{border-right-width:0}.next-table-loading{display:block;pointer-events:none;opacity:.7;-webkit-filter:blur(1px);filter:blur(1px);filter:"progid:DXImageTransform.Microsoft.Blur(PixelRadius=1, MakeShadow=false)"}.next-table-loading .next-table-loading-content{position:absolute;top:0;right:0;bottom:0;left:0}.next-table.zebra tr:nth-child(odd) td{background:#fff}.next-table.zebra tr:nth-child(2n) td{background:#fafafa}.next-table.zebra .next-table-cell.hovered,.next-table.zebra .next-table-row.hovered td{background:#fafafa;color:#333}.next-table.zebra .next-table-row.selected td{background:#f9f9f9;color:#333}.next-table-empty{color:#ccc;padding:32px 0;text-align:center}.next-table-expanded-row>td{border-width:0 0 1px}.next-table-expanded-row>td:first-child{border-left-width:1px}.next-table-expanded-row>td:last-child{border-right-width:1px}.next-table-expanded-row:last-child>td{border-bottom-width:1px}.next-table-expanded-row .next-table{border-top:0;border-left:0}.next-table-expanded-row .next-table td,.next-table-expanded-row .next-table th{border-right:1px solid #e6e6e6}.next-table-expanded-row .next-table.only-bottom-border td,.next-table-expanded-row .next-table.only-bottom-border th{border-right:0}.next-table-expanded-row .next-table .last td{border-bottom:0}.next-table-expanded-row .next-table td.last,.next-table-expanded-row .next-table th:last-child{border-right:0}.next-table-filter-footer{margin:10px 10px 0}.next-table-filter-footer button{margin-right:5px}.next-table-row{transition:all .1s linear;background:#fff;color:#333}.next-table-row.hidden{display:none}.next-table-row.hovered{background:#fafafa;color:#333}.next-table-row.selected{background:#f9f9f9;color:#333}.next-table-cell.hovered{background:#fafafa;color:#333}.next-table-tree-placeholder{visibility:hidden}.next-table-tree-placeholder .next-icon-remote,.next-table-tree-placeholder:before{width:12px;font-size:12px;line-height:inherit}.last .next-table-expanded-row td{border-bottom-width:1px}.next-table-body,.next-table-header{overflow:auto;font-size:14px}.next-table-column-resize-proxy{position:absolute;top:0;bottom:0;width:0;border-left:2px solid #209bfa;z-index:10;display:none}.next-table-header{margin-bottom:-20px;padding-bottom:20px;border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:0;border-bottom-right-radius:0;overflow:-moz-scrollbars-none;-ms-overflow-style:none;scrollbar-width:none}.next-table-header::-webkit-scrollbar{display:none}.next-table-body{font-size:14px;position:relative}.next-table-fixed{border-right:1px solid #e6e6e6;border-bottom:1px solid #e6e6e6}.next-table-fixed table{table-layout:fixed}.next-table-fixed .next-table-header{background:#f5f5f5}.next-table-fixed table tr td:first-child,.next-table-fixed table tr th:first-child{border-left-width:0}.next-table-fixed .next-table-header th{border-top-width:0}.next-table-fixed .next-table-header tr th:last-child{border-right-width:0}.next-table-fixed .next-table-body td{border-top-width:0}.next-table-fixed .next-table-body tr:last-child td{border-bottom-width:0}.next-table-fixed .next-table-body tr td:last-child{border-right-width:0}.next-table-fixed.only-bottom-border .next-table-body tr:last-child td{border-bottom-width:1px}.next-table-fixed.next-table-group table tr td:first-child,.next-table-fixed.next-table-group table tr th:first-child{border-left-width:1px}.next-table-fixed.next-table-group .next-table-header th{border-top-width:1px}.next-table-fixed.next-table-group .next-table-header tr th:last-child{border-right-width:1px}.next-table-fixed.next-table-group .next-table-body td{border-top-width:1px}.next-table-fixed.next-table-group .next-table-body tr:last-child td{border-bottom-width:1px}.next-table-fixed.next-table-group .next-table-body tr td:last-child,.next-table-fixed.next-table-lock-left .next-table-body tr td:last-child,.next-table-fixed.next-table-lock-left .next-table-header tr th:last-child{border-right-width:1px}.next-table-lock .next-table-body{overflow-x:auto;overflow-y:visible}.next-table-group{border-width:0}.next-table-group.only-bottom-border .next-table-body table,.next-table-group.only-bottom-border .next-table-header table{border-left:0}.next-table-group.only-bottom-border .next-table-body table,.next-table-group.only-bottom-border .next-table-body table.next-table-row,.next-table-group.only-bottom-border .next-table-header table{border-top:0}.next-table-group.only-bottom-border .next-table-body .next-table-group-footer td{border-bottom:0}.next-table-group .next-table-body{margin-top:8px}.next-table-group .next-table-body table{border-top:1px solid #e6e6e6;border-left:1px solid #e6e6e6;margin-bottom:8px}.next-table-group .next-table-body table tr:first-child td{border-top-width:1px}.next-table-group .next-table-body table:last-of-type{margin-bottom:0}.next-table-group .next-table-header table{border-top:1px solid #e6e6e6;border-left:1px solid #e6e6e6}.next-table-group .next-table-group-header td{background:#f5f5f5;color:#333}.next-table-group .next-table-group-header td:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.next-table-group .next-table-group-header td:last-child{border-top-right-radius:0;border-bottom-right-radius:0}.next-table-group .next-table-group-footer td{background:#f5f5f5;color:#333}.next-table-group .next-table-group-footer td:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.next-table-group .next-table-group-footer td:last-child{border-top-right-radius:0;border-bottom-right-radius:0}.next-table-group .next-table-row.hovered,.next-table-group .next-table-row.selected{background:#fff;color:#333}.next-table-lock{position:relative}.next-table-lock table{table-layout:fixed}.next-table-header-inner{overflow:unset}.next-table-header-fixer{content:" ";border-top-right-radius:0;border-bottom-right-radius:0;width:15px;background:inherit;position:absolute;right:0;height:100%;top:0}.next-table-wrap-empty .next-table-lock-left td,.next-table-wrap-empty .next-table-lock-right td{border:none}.next-table-wrap-empty .next-table-lock-left .next-table-empty,.next-table-wrap-empty .next-table-lock-right .next-table-empty{display:none}.next-table-wrap-empty>.next-table-inner>.next-table-body>table{table-layout:fixed}.next-table-lock-left,.next-table-lock-right{position:absolute;left:0;top:0;z-index:1;border:0;transition:box-shadow .3s ease;overflow:hidden}.next-table-lock-left table,.next-table-lock-right table{width:auto}.next-table-lock-left .next-table-body,.next-table-lock-right .next-table-body{overflow-y:scroll;overflow-x:hidden;margin-right:-20px;padding-right:0}.next-table-lock-left.shadow .next-table-body tr td:last-child,.next-table-lock-left.shadow .next-table-header tr th:last-child,.next-table-lock-right.shadow .next-table-body tr td:last-child,.next-table-lock-right.shadow .next-table-header tr th:last-child{border-right-width:0}.next-table-lock-right{right:0;left:auto}.next-table-lock-right table tr td:first-child,.next-table-lock-right table tr th:first-child{border-left-width:1px}.next-table-lock-right.shadow{box-shadow:-2px 0 3px rgba(0,0,0,.12)}.next-table-lock-left.shadow{box-shadow:2px 0 3px rgba(0,0,0,.12)}.next-table-filter{line-height:1}.next-table-sort{cursor:pointer;position:relative;width:16px;display:inline-block;line-height:1}.next-table-sort:focus{outline:0}.next-table-sort>a:before{content:" ";display:inline-block;vertical-align:middle}.next-table-sort .next-icon{position:absolute;left:-2px;color:#333}.next-table-sort .next-icon .next-icon-remote,.next-table-sort .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-table-sort .current .next-icon{color:#209bfa}.next-table-sort .next-icon-ascending{left:2px}.next-table-filter{cursor:pointer;width:20px;display:inline-block}.next-table-filter:focus{outline:0}.next-table-filter .next-icon{color:#333}.next-table-filter .next-icon .next-icon-remote,.next-table-filter .next-icon:before{width:12px;font-size:12px;line-height:inherit}.next-table-filter .next-table-filter-active{color:#209bfa}.next-table-filter-menu .next-menu-content{max-height:220px;overflow:auto}.next-table-header-icon{margin-left:8px}.next-table-expanded-ctrl{cursor:pointer}.next-table-expanded-ctrl:focus{outline:0}.next-table-expanded-ctrl.disabled{color:#999}.next-table-expanded-ctrl .next-table-expand-unfold .next-icon-remote,.next-table-expanded-ctrl .next-table-expand-unfold:before{width:12px;font-size:12px;line-height:inherit}.next-table-expanded-ctrl .next-table-expand-unfold:before{content:""}.next-table-expanded-ctrl .next-table-expand-fold .next-icon-remote,.next-table-expanded-ctrl .next-table-expand-fold:before{width:12px;font-size:12px;line-height:inherit}.next-table-expanded-ctrl .next-table-expand-fold:before{content:""}.next-table-fix-left,.next-table-fix-right{background:inherit;position:sticky;z-index:1;background-clip:padding-box}.next-table-ping-left .next-table-expanded-area .next-table-fix-left-last:after{content:none}.next-table-ping-left .next-table-expanded-area .next-table-ping-left .next-table-fix-left-last,.next-table-ping-left .next-table-fix-left-last{border-right-width:0}.next-table-ping-left .next-table-expanded-area .next-table-ping-left .next-table-fix-left-last:after,.next-table-ping-left .next-table-fix-left-last:after{box-shadow:inset 10px 0 8px -8px rgba(0,0,0,.15);position:absolute;top:0;right:0;bottom:0;width:30px;content:"";pointer-events:none;transition:box-shadow .3s,-webkit-box-shadow .3s;transform:translateX(100%)}.next-table-ping-right .next-table-expanded-area .next-table-fix-right-first:after{content:none}.next-table-ping-right .next-table-expanded-area .next-table-ping-right .next-table-fix-right-first:after,.next-table-ping-right .next-table-fix-right-first:after{box-shadow:inset -10px 0 8px -8px rgba(0,0,0,.15);position:absolute;top:0;left:0;bottom:0;width:30px;content:"";pointer-events:none;transition:box-shadow .3s,-webkit-box-shadow .3s;transform:translateX(-100%)}.next-table-fixed.next-table-scrolling-to-right:after,.next-table-lock.next-table-scrolling-to-right:after{box-shadow:inset -10px 0 8px -8px rgba(0,0,0,.15);position:absolute;top:0;right:-30px;bottom:0;width:30px;content:"";pointer-events:none;transition:box-shadow .3s,-webkit-box-shadow .3s;transform:translateX(-100%)}.next-table-fixed.only-bottom-border,.next-table-lock.only-bottom-border{border-right:0}.next-table[dir=rtl] th{text-align:right}.next-table[dir=rtl] .next-table-header-resizable .next-table-resize-handler{right:auto;left:0}.next-table[dir=rtl] td .next-table-cell-wrapper .next-icon-arrow-down.next-table-tree-arrow,.next-table[dir=rtl] td .next-table-cell-wrapper .next-icon-arrow-right.next-table-tree-arrow,.next-table[dir=rtl] td .next-table-cell-wrapper .next-table-tree-placeholder{margin-left:3px;margin-right:0;float:right}.next-table[dir=rtl] .next-table-expanded-row td:first-child{border-left-width:0;border-right-width:1px}.next-table[dir=rtl] .next-table-expanded-row td:last-child{border-left-width:1px;border-right-width:0}.next-table[dir=rtl].only-bottom-border .next-table-expanded-row td,.next-table[dir=rtl].only-bottom-border .next-table-expanded-row th{border-width:0 0 1px}.next-table[dir=rtl] .next-table-filter-footer button{margin-left:5px;margin-right:0}.next-table[dir=rtl] .next-table-lock-left,.next-table[dir=rtl] .next-table-lock-right{left:auto;right:0}.next-table[dir=rtl] .next-table-lock-right{right:auto;left:0}.next-table[dir=rtl] .next-table-lock-right table tr td:first-child,.next-table[dir=rtl] .next-table-lock-right table tr th:first-child{border-right-width:1px}.next-table[dir=rtl] .next-table-lock-right.shadow{box-shadow:2px 0 3px rgba(0,0,0,.12)}.next-table[dir=rtl] .next-table-lock-left.shadow{box-shadow:-2px 0 3px rgba(0,0,0,.12)}.next-table[dir=rtl] .next-table-sort .next-icon{right:0;left:auto}.next-table[dir=rtl] .next-table-sort .next-icon-ascending{right:4px;left:auto}.next-table[dir=rtl] .next-table-filter{margin-right:5px;margin-left:0}.next-table-fixed[dir=rtl] table tr td:first-child,.next-table-fixed[dir=rtl] table tr th:first-child{border-left-width:1px;border-right-width:0}.next-table-fixed[dir=rtl] .next-table-body tr td:last-child,.next-table-fixed[dir=rtl] .next-table-header tr th:last-child{border-left-width:1px}.next-calendar2,.next-calendar2 *,.next-calendar2 :after,.next-calendar2 :before{box-sizing:border-box}.next-calendar2 table{border-collapse:collapse;border-spacing:0}.next-calendar2 td,.next-calendar2 th{padding:0}div[dir=rtl].next-calendar2-card .next-calendar2-header-actions,div[dir=rtl].next-calendar2-fullscreen .next-calendar2-header-actions,div[dir=rtl].next-calendar2-panel .next-calendar2-header-actions{margin-right:auto;margin-left:0}div[dir=rtl].next-calendar2-card .next-calendar2-header-actions>:not(:first-child),div[dir=rtl].next-calendar2-card .next-calendar2-header-ranges>:not(:first-child),div[dir=rtl].next-calendar2-fullscreen .next-calendar2-header-actions>:not(:first-child),div[dir=rtl].next-calendar2-fullscreen .next-calendar2-header-ranges>:not(:first-child),div[dir=rtl].next-calendar2-panel .next-calendar2-header-actions>:not(:first-child),div[dir=rtl].next-calendar2-panel .next-calendar2-header-ranges>:not(:first-child){margin-right:8px;margin-left:0}div[dir=rtl].next-calendar2-fullscreen .next-calendar2-cell-value,div[dir=rtl].next-calendar2-fullscreen .next-calendar2-table th{text-align:left}div[dir=rtl].next-calendar2-fullscreen .next-calendar2-table th{padding:0 0 5px 12px}.next-calendar2{font-size:12px;user-select:none;background:#fff}.next-calendar2-header{display:flex}.next-calendar2-table{width:100%;table-layout:fixed}.next-calendar2-cell{cursor:pointer;position:relative;transition:background-color .2s,border .2s}.next-calendar2 .next-calendar2-cell-inner{color:#ccc;outline:none;min-width:24px;position:relative;border:1px solid transparent}.next-calendar2-cell-disabled:before{color:#ccc;background:#fafafa}.next-calendar2-card .next-calendar2-header-actions,.next-calendar2-fullscreen .next-calendar2-header-actions,.next-calendar2-panel .next-calendar2-header-actions{margin-left:auto}.next-calendar2-card .next-calendar2-header-actions>:not(:first-child),.next-calendar2-card .next-calendar2-header-ranges>:not(:first-child),.next-calendar2-fullscreen .next-calendar2-header-actions>:not(:first-child),.next-calendar2-fullscreen .next-calendar2-header-ranges>:not(:first-child),.next-calendar2-panel .next-calendar2-header-actions>:not(:first-child),.next-calendar2-panel .next-calendar2-header-ranges>:not(:first-child){margin-left:8px}.next-calendar2-card .next-calendar2-header-select-month,.next-calendar2-card .next-calendar2-header-select-year,.next-calendar2-fullscreen .next-calendar2-header-select-month,.next-calendar2-fullscreen .next-calendar2-header-select-year,.next-calendar2-panel .next-calendar2-header-select-month,.next-calendar2-panel .next-calendar2-header-select-year{min-width:88px}.next-calendar2-card .next-calendar2-header-select-month .next-input,.next-calendar2-card .next-calendar2-header-select-year .next-input,.next-calendar2-fullscreen .next-calendar2-header-select-month .next-input,.next-calendar2-fullscreen .next-calendar2-header-select-year .next-input,.next-calendar2-panel .next-calendar2-header-select-month .next-input,.next-calendar2-panel .next-calendar2-header-select-year .next-input{min-width:auto}.next-calendar2-card .next-calendar2-body,.next-calendar2-fullscreen .next-calendar2-body,.next-calendar2-panel .next-calendar2-body{padding:8px 0}.next-calendar2-card .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-cell-inner{z-index:2;height:24px;line-height:22px;border-radius:2px;display:inline-block}.next-calendar2-card .next-calendar2,.next-calendar2-panel .next-calendar2{min-height:150px}.next-calendar2-card .next-calendar2-table thead>tr,.next-calendar2-panel .next-calendar2-table thead>tr{height:24px;color:#999}.next-calendar2-card .next-calendar2-table td,.next-calendar2-card .next-calendar2-table th,.next-calendar2-panel .next-calendar2-table td,.next-calendar2-panel .next-calendar2-table th{font-weight:400;text-align:center;padding:4px 0}.next-calendar2-card .next-calendar2-table th,.next-calendar2-panel .next-calendar2-table th{height:32px}.next-calendar2-card .next-calendar2-table-decade,.next-calendar2-card .next-calendar2-table-month,.next-calendar2-card .next-calendar2-table-year,.next-calendar2-panel .next-calendar2-table-decade,.next-calendar2-panel .next-calendar2-table-month,.next-calendar2-panel .next-calendar2-table-year{height:145px}.next-calendar2-card .next-calendar2-table-decade .next-calendar2-cell-inner,.next-calendar2-card .next-calendar2-table-month .next-calendar2-cell-inner,.next-calendar2-card .next-calendar2-table-year .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-table-decade .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-table-month .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-table-year .next-calendar2-cell-inner{min-width:56px}.next-calendar2-card .next-calendar2-table-quarter,.next-calendar2-panel .next-calendar2-table-quarter{height:50px}.next-calendar2-card .next-calendar2-table-quarter .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-table-quarter .next-calendar2-cell-inner{min-width:56px}.next-calendar2-card .next-calendar2-table-decade .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-table-decade .next-calendar2-cell-inner{min-width:80px}.next-calendar2-card .next-calendar2-cell-current:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):not(.next-calendar2-cell-today) .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-cell-current:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):not(.next-calendar2-cell-today) .next-calendar2-cell-inner{color:#666}.next-calendar2-card .next-calendar2-cell-current:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):not(.next-calendar2-cell-today):hover:not(.next-calendar2-cell-hover) .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-cell-current:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):not(.next-calendar2-cell-today):hover:not(.next-calendar2-cell-hover) .next-calendar2-cell-inner{background:#f9f9f9}.next-calendar2-card .next-calendar2-cell-current.next-calendar2-cell-today:not(.next-calendar2-cell-disabled) .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-cell-current.next-calendar2-cell-today:not(.next-calendar2-cell-disabled) .next-calendar2-cell-inner{color:#209bfa}.next-calendar2-card .next-calendar2-cell-current.next-calendar2-cell-selected:not(.next-calendar2-cell-disabled) .next-calendar2-cell-inner,.next-calendar2-panel .next-calendar2-cell-current.next-calendar2-cell-selected:not(.next-calendar2-cell-disabled) .next-calendar2-cell-inner{color:#fff;background:#209bfa}.next-calendar2-fullscreen .next-calendar2-cell-value,.next-calendar2-fullscreen .next-calendar2-table th{text-align:right}.next-calendar2-fullscreen .next-calendar2-table th{padding:0 12px 5px 0}.next-calendar2-fullscreen .next-calendar2-cell-inner{height:80px;border-top:2px solid #eee;margin:0 4px;padding:4px 8px 0}.next-calendar2-fullscreen td .next-calendar2-cell-inner{height:80px;border-top:2px solid #eee}.next-calendar2-fullscreen .next-calendar2-cell-disabled .next-calendar2-cell-inner{color:#ccc;background:#fafafa}.next-calendar2-fullscreen .next-calendar2-cell-current:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):not(.next-calendar2-cell-today) .next-calendar2-cell-inner{color:#666}.next-calendar2-fullscreen .next-calendar2-cell-current:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):not(.next-calendar2-cell-today):hover .next-calendar2-cell-inner{background-color:#f9f9f9}.next-calendar2-fullscreen .next-calendar2-cell-current.next-calendar2-cell-today .next-calendar2-cell-inner{color:#209bfa}.next-calendar2-fullscreen .next-calendar2-cell-current .next-calendar2-cell-inner{background-color:#fff}.next-calendar2-fullscreen .next-calendar2-cell-current.next-calendar2-cell-selected:not(.next-calendar2-cell-disabled) .next-calendar2-cell-inner{border-top-color:#209bfa;font-weight:700;color:#209bfa;background:#add9ff}.next-calendar2-card .next-calendar2-header{padding:8px;border-bottom:1px solid #eee}.next-calendar2-panel .next-calendar2-header{padding:0 8px;display:flex;align-items:center;border-bottom:1px solid #eee}.next-calendar2-panel .next-calendar2-header-btn{min-width:20px;line-height:20px;color:#666;font-family:inherit;vertical-align:initial;border-radius:2px}.next-calendar2-panel .next-calendar2-header-btn>span,.next-calendar2-panel .next-calendar2-header-text-field{text-align:center;font-size:14px;color:#333;font-weight:bolder;vertical-align:initial}.next-calendar2-panel .next-calendar2-header-btn:hover,.next-calendar2-panel .next-calendar2-header-btn:hover>span{color:#209bfa}.next-calendar2-panel .next-calendar2-header-left-btn:hover,.next-calendar2-panel .next-calendar2-header-right-btn:hover{background:#f9f9f9}.next-calendar2-panel .next-calendar2-header-text-field{flex:1;height:38px;line-height:38px}.next-calendar2-panel .next-calendar2-header-text-field .next-calendar2-header-btn:not(:first-child){margin-left:6px}.next-calendar2-header-select-month-popup,.next-calendar2-header-select-year-popup{min-width:auto}.next-time-picker2-menu{float:left;text-align:center;padding:8px 0}.next-time-picker2-menu:not(:last-child){border-right:1px solid #e6e6e6}.next-time-picker2-menu-title{cursor:default;height:28px;line-height:28px;font-size:12px;font-weight:400;color:#999;background:#fff}.next-time-picker2-menu ul{position:relative;overflow-y:hidden;overflow-x:auto;list-style:none;margin:0;width:54px;padding:0;font-size:12px;height:224px;scrollbar-width:none;-ms-overflow-style:none}.next-time-picker2-menu ul::-webkit-scrollbar{width:0}.next-time-picker2-menu ul:hover{overflow-y:auto}.next-time-picker2-menu ul:after{display:block;height:192px;content:""}.next-time-picker2-menu-item{cursor:pointer;height:32px;line-height:32px;transition:background .1s linear;color:#666;background:#fff;outline:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.next-time-picker2-menu-item:hover{color:#333;background:#f9f9f9}.next-time-picker2-menu-item.next-selected{color:#666;background:#add9ff}.next-time-picker2-menu-item.next-disabled{cursor:not-allowed;color:#ccc;background:#fafafa}.next-time-picker2-panel{box-sizing:border-box;display:flex}.next-time-picker2-panel *,.next-time-picker2-panel :after,.next-time-picker2-panel :before{box-sizing:border-box}.next-time-picker2-panel:after{visibility:hidden;display:block;height:0;font-size:0;content:" ";clear:both}.next-time-picker2-panel-header{border-bottom:1px solid #e6e6e6}.next-time-picker2-panel-input.next-input{width:100%;padding:6px;border-color:transparent;vertical-align:middle}.next-time-picker2-panel .next-time-picker2-menu{flex:1}.next-time-picker2-panel-range .next-time-picker2-panel-list:last-of-type{margin-left:20px}.next-time-picker2-footer{width:min-content;min-width:100%;box-sizing:border-box;text-align:center;border-top:1px solid #f0f0f0;padding:4px 12px;display:flex;min-height:40px;align-items:center;flex-wrap:wrap}.next-time-picker2-footer-actions{margin-left:auto}.next-time-picker2-wrapper[dir=rtl] .next-time-picker2-menu{float:right}.next-time-picker2-wrapper[dir=rtl] .next-time-picker2-menu:not(:last-child){border-right:none;border-left:1px solid #e6e6e6}.next-time-picker2{display:inline-block}.next-time-picker2,.next-time-picker2 *,.next-time-picker2 :after,.next-time-picker2 :before{box-sizing:border-box}.next-time-picker2-trigger .next-input{width:100%}.next-time-picker2-wrapper{padding:4px 0}.next-time-picker2-body{display:block;overflow:hidden;border:1px solid #e6e6e6;border-radius:3px;background:#fff;box-shadow:none}.next-time-picker2-symbol-clock-icon:before{content:""}.next-time-picker2-input{display:inline-flex;align-items:center;outline:none;box-sizing:border-box;border:1px solid #ddd;vertical-align:middle;width:inherit}.next-time-picker2-input .next-input{border:none;width:100%;height:100%}.next-time-picker2-input .next-input input{height:100%}.next-time-picker2-input.next-time-picker2-input-small{height:24px;border-radius:3px}.next-time-picker2-input.next-time-picker2-input-small .next-input-label{padding-left:8px;font-size:12px}.next-time-picker2-input.next-time-picker2-input-small .next-input-inner{font-size:12px}.next-time-picker2-input.next-time-picker2-input-small .next-input-control,.next-time-picker2-input.next-time-picker2-input-small .next-input-inner-text{padding-right:4px}.next-time-picker2-input.next-time-picker2-input-small input{height:22px;line-height:22px \0 ;padding:0 4px;font-size:12px}.next-time-picker2-input.next-time-picker2-input-small input::placeholder{font-size:12px}.next-time-picker2-input.next-time-picker2-input-small .next-input-text-field{padding:0 4px;font-size:12px;height:22px;line-height:22px}.next-time-picker2-input.next-time-picker2-input-small .next-icon .next-icon-remote,.next-time-picker2-input.next-time-picker2-input-small .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-time-picker2-input.next-time-picker2-input-small .next-input-control{border-radius:0 3px 3px 0}.next-time-picker2-input.next-time-picker2-input-medium{height:32px;border-radius:3px}.next-time-picker2-input.next-time-picker2-input-medium .next-input-label{padding-left:8px;font-size:14px}.next-time-picker2-input.next-time-picker2-input-medium .next-input-inner{font-size:14px}.next-time-picker2-input.next-time-picker2-input-medium .next-input-control,.next-time-picker2-input.next-time-picker2-input-medium .next-input-inner-text{padding-right:8px}.next-time-picker2-input.next-time-picker2-input-medium input{height:30px;line-height:30px \0 ;padding:0 8px;font-size:14px}.next-time-picker2-input.next-time-picker2-input-medium input::placeholder{font-size:14px}.next-time-picker2-input.next-time-picker2-input-medium .next-input-text-field{padding:0 8px;font-size:14px;height:30px;line-height:30px}.next-time-picker2-input.next-time-picker2-input-medium .next-icon .next-icon-remote,.next-time-picker2-input.next-time-picker2-input-medium .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-time-picker2-input.next-time-picker2-input-medium .next-input-control{border-radius:0 3px 3px 0}.next-time-picker2-input.next-time-picker2-input-large{height:40px;border-radius:3px}.next-time-picker2-input.next-time-picker2-input-large .next-input-label{padding-left:12px;font-size:16px}.next-time-picker2-input.next-time-picker2-input-large .next-input-inner{font-size:16px}.next-time-picker2-input.next-time-picker2-input-large .next-input-control,.next-time-picker2-input.next-time-picker2-input-large .next-input-inner-text{padding-right:8px}.next-time-picker2-input.next-time-picker2-input-large input{height:38px;line-height:38px \0 ;padding:0 12px;font-size:16px}.next-time-picker2-input.next-time-picker2-input-large input::placeholder{font-size:16px}.next-time-picker2-input.next-time-picker2-input-large .next-input-text-field{padding:0 12px;font-size:16px;height:38px;line-height:38px}.next-time-picker2-input.next-time-picker2-input-large .next-icon .next-icon-remote,.next-time-picker2-input.next-time-picker2-input-large .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-time-picker2-input.next-time-picker2-input-large .next-input-control{border-radius:0 3px 3px 0}.next-time-picker2-input:hover{border-color:#ccc;background-color:#fff}.next-time-picker2-input.next-time-picker2-input-focus{border-color:#209bfa;background-color:#fff;box-shadow:0 0 0 2px rgba(32,155,250,.2)}.next-time-picker2-input.next-time-picker2-input-noborder{border-color:transparent!important;box-shadow:none!important}.next-time-picker2-input.next-time-picker2-input-disabled{color:#ccc;border-color:#eee;background-color:#fafafa;cursor:not-allowed}.next-time-picker2-input.next-time-picker2-input-disabled:hover{border-color:#eee;background-color:#fafafa}.next-time-picker2-input.next-time-picker2-input-error{border-color:#d23c26}.next-time-picker2-input-separator{color:#ddd;font-size:12px;display:inline-block;min-width:16px;text-align:center}.next-sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;top:0;margin:-1px}.next-date-picker2-footer{width:min-content;min-width:100%;box-sizing:border-box;text-align:center;border-top:1px solid #eee;padding:4px 12px;display:flex;min-height:40px;align-items:center;flex-wrap:wrap;position:relative}.next-date-picker2-footer-preset>.next-btn{margin-right:8px}.next-date-picker2-footer-actions{margin-left:auto}.next-date-picker2-footer-preset-only{width:100%}div[dir=rtl] .next-date-picker2-footer-preset>.next-btn{margin-left:8px;margin-right:0}div[dir=rtl] .next-date-picker2-footer-actions{margin-left:0;margin-right:auto}div[dir=rtl] .next-date-picker2-wrapper .next-calendar2-cell:last-child:before{border-top-right-radius:0;border-bottom-right-radius:0;right:0;border-top-left-radius:2px;border-bottom-left-radius:2px;left:8px}div[dir=rtl] .next-date-picker2-wrapper .next-calendar2-cell:first-child:before{border-top-left-radius:0;border-bottom-left-radius:0;left:0;border-top-right-radius:2px;border-bottom-right-radius:2px;right:8px}div[dir=rtl] .next-date-time-picker-wrapper{border-right:1px solid #eee;border-left:none}div[dir=rtl] .next-date-time-picker-wrapper .next-time-picker2-menu:not(:last-child){border-left:1px solid #dcdee3;border-right:none}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-selected.next-calendar2-cell-range-begin:before{right:50%;left:0}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-selected.next-calendar2-cell-range-end:before{left:50%;right:0}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover.next-calendar2-cell-hover-begin:after,div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:first-child:after{right:8px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover.next-calendar2-cell-hover-begin:not(:last-child):after,div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:first-child:not(.next-calendar2-cell-hover-end):after{left:0}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover.next-calendar2-cell-hover-end:after,div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:last-child:after{left:8px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover.next-calendar2-cell-hover-end:not(:first-child):after,div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:last-child:not(.next-calendar2-cell-hover-begin):after{right:0}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover.next-calendar2-cell-selected.next-calendar2-cell-hover-begin:after{left:0;right:7px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover.next-calendar2-cell-selected.next-calendar2-cell-hover-end:after{right:0;left:7px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:first-of-type:after{border-top-left-radius:0;border-bottom-left-radius:0;border-left:none;border-top-right-radius:2px;border-bottom-right-radius:2px;border-right:1px dashed #1274e7}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:last-of-type:after{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none;border-top-left-radius:2px;border-bottom-left-radius:2px;border-left:1px dashed #1274e7}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-edge-end:after,div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-edge-end:before{right:0;left:8px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-edge-end.next-calendar2-cell-hover:after{border-top-right-radius:0;border-bottom-right-radius:0;border-right:none;border-top-left-radius:2px;border-bottom-left-radius:2px;border-left:1px dashed #1274e7}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover-begin:after{border-left:none;border-top-left-radius:0;border-bottom-left-radius:0;border-right:1px dashed #1274e7;border-top-right-radius:2px;border-bottom-right-radius:2px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover-end:after{border-right:none;border-top-right-radius:0;border-bottom-right-radius:0;border-left:1px dashed #1274e7;border-top-left-radius:2px;border-bottom-left-radius:2px}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled):after,div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled):before{right:8px;left:0}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:after{right:8px;border-top-right-radius:2px;border-bottom-right-radius:2px;border-right:1px dashed #1274e7}div[dir=rtl] .next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:not(.next-calendar2-cell-hover-end):not(.next-calendar2-cell-hover-begin):after{border-top-left-radius:0;border-bottom-left-radius:0;border-left:none}div[dir=rtl] .next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:nth-child(2):before{right:50%;left:0}div[dir=rtl] .next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:last-child:before{left:50%;right:0}.next-date-picker2{outline:none;display:inline-table;position:relative;width:inherit}.next-date-picker2-overlay{vertical-align:top;padding:4px 0}.next-date-picker2-overlay-range{padding:12px 0}.next-date-picker2-wrapper{box-shadow:0 4px 16px 0 rgba(0,0,0,.12);background-color:#fff;border:1px solid #eee;border-radius:3px}.next-date-picker2-wrapper .next-calendar2-panel{border-radius:3px}.next-date-picker2-wrapper .next-calendar2-body{width:272px}.next-date-picker2-wrapper .next-calendar2-cell:before{content:"";position:absolute;top:50%;right:0;left:0;z-index:1;height:24px;transform:translateY(-50%)}.next-date-picker2-wrapper .next-calendar2-cell:last-child:before{border-top-right-radius:2px;border-bottom-right-radius:2px;right:8px}.next-date-picker2-wrapper .next-calendar2-cell:first-child:before{border-top-left-radius:2px;border-bottom-left-radius:2px;left:8px}.next-date-picker2-input{display:inline-flex;align-items:center;outline:none;box-sizing:border-box;border:1px solid #ddd;vertical-align:middle;width:inherit;background-color:#fff}.next-date-picker2-input .next-input{border:none;flex-basis:100%;height:100%;width:100%}.next-date-picker2-input .next-input input{height:100%;width:auto}.next-date-picker2-input.next-date-picker2-input-small{height:24px;border-radius:3px}.next-date-picker2-input.next-date-picker2-input-small .next-input-label{padding-left:8px;font-size:12px}.next-date-picker2-input.next-date-picker2-input-small .next-input-inner{font-size:12px}.next-date-picker2-input.next-date-picker2-input-small .next-input-control,.next-date-picker2-input.next-date-picker2-input-small .next-input-inner-text{padding-right:4px}.next-date-picker2-input.next-date-picker2-input-small input{height:22px;line-height:22px \0 ;padding:0 4px;font-size:12px}.next-date-picker2-input.next-date-picker2-input-small input::placeholder{font-size:12px}.next-date-picker2-input.next-date-picker2-input-small .next-input-text-field{padding:0 4px;font-size:12px;height:22px;line-height:22px}.next-date-picker2-input.next-date-picker2-input-small .next-icon .next-icon-remote,.next-date-picker2-input.next-date-picker2-input-small .next-icon:before{width:16px;font-size:16px;line-height:inherit}.next-date-picker2-input.next-date-picker2-input-small .next-input-control{border-radius:0 3px 3px 0}.next-date-picker2-input.next-date-picker2-input-medium{height:32px;border-radius:3px}.next-date-picker2-input.next-date-picker2-input-medium .next-input-label{padding-left:8px;font-size:14px}.next-date-picker2-input.next-date-picker2-input-medium .next-input-inner{font-size:14px}.next-date-picker2-input.next-date-picker2-input-medium .next-input-control,.next-date-picker2-input.next-date-picker2-input-medium .next-input-inner-text{padding-right:8px}.next-date-picker2-input.next-date-picker2-input-medium input{height:30px;line-height:30px \0 ;padding:0 8px;font-size:14px}.next-date-picker2-input.next-date-picker2-input-medium input::placeholder{font-size:14px}.next-date-picker2-input.next-date-picker2-input-medium .next-input-text-field{padding:0 8px;font-size:14px;height:30px;line-height:30px}.next-date-picker2-input.next-date-picker2-input-medium .next-icon .next-icon-remote,.next-date-picker2-input.next-date-picker2-input-medium .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-date-picker2-input.next-date-picker2-input-medium .next-input-control{border-radius:0 3px 3px 0}.next-date-picker2-input.next-date-picker2-input-large{height:40px;border-radius:3px}.next-date-picker2-input.next-date-picker2-input-large .next-input-label{padding-left:12px;font-size:16px}.next-date-picker2-input.next-date-picker2-input-large .next-input-inner{font-size:16px}.next-date-picker2-input.next-date-picker2-input-large .next-input-control,.next-date-picker2-input.next-date-picker2-input-large .next-input-inner-text{padding-right:8px}.next-date-picker2-input.next-date-picker2-input-large input{height:38px;line-height:38px \0 ;padding:0 12px;font-size:16px}.next-date-picker2-input.next-date-picker2-input-large input::placeholder{font-size:16px}.next-date-picker2-input.next-date-picker2-input-large .next-input-text-field{padding:0 12px;font-size:16px;height:38px;line-height:38px}.next-date-picker2-input.next-date-picker2-input-large .next-icon .next-icon-remote,.next-date-picker2-input.next-date-picker2-input-large .next-icon:before{width:20px;font-size:20px;line-height:inherit}.next-date-picker2-input.next-date-picker2-input-large .next-input-control{border-radius:0 3px 3px 0}.next-date-picker2-input:hover{border-color:#ccc;background-color:#fff}.next-date-picker2-input.next-date-picker2-input-focus{border-color:#209bfa;background-color:#fff;box-shadow:0 0 0 2px rgba(32,155,250,.2)}.next-date-picker2-input.next-date-picker2-input-noborder{border-color:transparent!important;box-shadow:none!important}.next-date-picker2-input.next-date-picker2-input-disabled{color:#ccc;border-color:#eee;background-color:#fafafa;cursor:not-allowed}.next-date-picker2-input.next-date-picker2-input-disabled:hover{border-color:#eee;background-color:#fafafa}.next-date-picker2-input.next-date-picker2-input-error{border-color:#d23c26}.next-date-picker2-input-separator{color:#ddd;font-size:12px;line-height:12px;display:inline-block;min-width:16px;text-align:center}.next-date-picker2-panel,.next-range-picker2-panel{display:inline-flex}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-range-picker-left .next-calendar2-header-right-btn,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-range-picker-right .next-calendar2-header-left-btn{visibility:hidden}.next-range-picker2-arrow{display:block;transform:translateY(-50%) rotate(-45deg);position:absolute;z-index:1;width:10px;height:10px;margin-left:16.5px;border-color:#eee #eee transparent transparent;border-style:solid;border-width:1px;transition:left .3s ease-out;background:#fff}.next-date-picker2-tl-bl .next-range-picker2-arrow{top:12.5px}.next-date-picker2-bl-tl .next-range-picker2-arrow{bottom:13px;transform:translateY(50%) rotate(135deg)}.next-date-time-picker-wrapper{border-left:1px solid #eee}.next-date-time-picker-wrapper .next-calendar2-body{padding-right:0;padding-left:0}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-disabled .next-calendar2-cell-inner{color:#ccc;background:#fafafa}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected:before{color:#666;background:#add9ff}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected .next-calendar2-cell-inner{color:#666;background:transparent}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected.next-calendar2-cell-range-begin .next-calendar2-cell-inner,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected.next-calendar2-cell-range-end .next-calendar2-cell-inner{z-index:10;color:#fff;background:#209bfa}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected.next-calendar2-cell-range-begin:before{left:50%}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected.next-calendar2-cell-range-end:before{right:50%}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected.next-calendar2-cell-range-begin-single:before,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-selected.next-calendar2-cell-range-end-single:before{display:none}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover:after{content:"";position:absolute;top:50%;right:0;left:0;z-index:2;height:24px;transform:translateY(-50%);border-color:#1274e7 transparent;border-style:dashed;border-width:1px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover.next-calendar2-cell-hover-begin:after,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover:first-child:after{left:8px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover.next-calendar2-cell-hover-end:after,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover:last-child:after{right:8px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover.next-calendar2-cell-selected.next-calendar2-cell-hover-begin:after{left:8px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover.next-calendar2-cell-selected.next-calendar2-cell-hover-end:after{right:8px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover:first-of-type:after{border-top-left-radius:2px;border-bottom-left-radius:2px;border-left:1px dashed #1274e7}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover:last-of-type:after{border-top-right-radius:2px;border-bottom-right-radius:2px;border-right:1px dashed #1274e7}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-edge-end:after,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-edge-end:before{right:8px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-edge-end.next-calendar2-cell-hover:after{border-top-right-radius:2px;border-bottom-right-radius:2px;border-right:1px dashed #1274e7}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover-begin:after{border-top:1px dashed #1274e7;border-left:1px dashed #1274e7;border-top-left-radius:2px;border-bottom-left-radius:2px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-current.next-calendar2-cell-hover-end:after{border-top:1px dashed #1274e7;border-right:1px dashed #1274e7;border-top-right-radius:2px;border-bottom-right-radius:2px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled):after,.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled):before{left:8px}.next-range-picker2-panel:not(.next-range-picker2-panel-single) .next-calendar2-cell-edge-end+.next-calendar2-cell-current:not(.next-calendar2-cell-disabled).next-calendar2-cell-hover:after{border-top-left-radius:2px;border-bottom-left-radius:2px;border-left:1px dashed #1274e7}.next-calendar2-table-week .next-calendar2-cell-hover:after{display:none}.next-calendar2-table-week tr:hover .next-calendar2-cell:not(.next-calendar2-cell-disabled):not(.next-calendar2-cell-selected):before{background:#f9f9f9}.next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected .next-calendar2-cell-inner,.next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:before{color:#666;background-color:#add9ff}.next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:last-child .next-calendar2-cell-inner,.next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:nth-child(2) .next-calendar2-cell-inner{color:#fff;background:#209bfa}.next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:nth-child(2):before{left:50%}.next-calendar2-table-week .next-calendar2-week-current .next-calendar2-cell.next-calendar2-cell-selected:last-child:before{right:50%}.next-calendar2-table-week tr:not(.next-calendar2-week-current) td.next-calendar2-cell.next-calendar2-cell-selected:not(.next-calendar2-cell-disabled) .next-calendar2-cell-inner,.next-calendar2-table-week tr:not(.next-calendar2-week-current) td.next-calendar2-cell.next-calendar2-cell-selected:not(.next-calendar2-cell-disabled):before{background-color:transparent;color:#ccc}.next-range-picker2-panel .next-calendar2-week-current .next-calendar2-cell-selected:not(.next-calendar2-cell-disabled):last-child .next-calendar2-cell-inner,.next-range-picker2-panel .next-calendar2-week-current .next-calendar2-cell-selected:not(.next-calendar2-cell-disabled):nth-child(2) .next-calendar2-cell-inner{background-color:#add9ff;color:#666}.next-range-picker2-panel .next-calendar2-week-current .next-calendar2-cell-selected:not(.next-calendar2-cell-disabled).next-calendar2-cell-week-range-begin:last-child .next-calendar2-cell-inner,.next-range-picker2-panel .next-calendar2-week-current .next-calendar2-cell-selected:not(.next-calendar2-cell-disabled).next-calendar2-cell-week-range-begin:nth-child(2) .next-calendar2-cell-inner,.next-range-picker2-panel .next-calendar2-week-current .next-calendar2-cell-selected:not(.next-calendar2-cell-disabled).next-calendar2-cell-week-range-end:last-child .next-calendar2-cell-inner,.next-range-picker2-panel .next-calendar2-week-current .next-calendar2-cell-selected:not(.next-calendar2-cell-disabled).next-calendar2-cell-week-range-end:nth-child(2) .next-calendar2-cell-inner{color:#fff;background:#209bfa}.next-icon-alibaba:before{content:""}.next-icon-ic_dashboard:before{content:""}.next-icon-ic_form:before{content:""}.next-icon-ic_formbeifen:before{content:""}.next-icon-ic_language:before{content:""}.next-icon-ic_logo:before{content:""}.next-icon-ic_tongzhi:before{content:""}.next-icon-ic_yusuanguanli:before{content:""}.next-icon-taobao:before{content:""} \ No newline at end of file diff --git a/console/src/main/resources/static/console-ui/public/js/main.js b/console/src/main/resources/static/console-ui/public/js/main.js new file mode 100644 index 00000000000..4070e56d7f0 --- /dev/null +++ b/console/src/main/resources/static/console-ui/public/js/main.js @@ -0,0 +1,340 @@ +!function(n){var a={};function r(e){var t;return(a[e]||(t=a[e]={i:e,l:!1,exports:{}},n[e].call(t.exports,t,t.exports,r),t.l=!0,t)).exports}r.m=n,r.c=a,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)r.d(n,a,function(e){return t[e]}.bind(null,a));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=462)}([function(e,t,n){"use strict";e.exports=n(469)},function(e,t,n){"use strict";n.d(t,"b",function(){return T}),n.d(t,"f",function(){return L}),n.d(t,"c",function(){return m}),n.d(t,"d",function(){return a}),n.d(t,"a",function(){return o}),n.d(t,"e",function(){return O});n(48);var t=n(25),c=n.n(t),l=n(76),r=n(94),d=n(62),f=n(32),t=n(111),u=n.n(t),t=n(68),p=n.n(t),h=n(22);function m(){var e=window.location.href,e=(localStorage.removeItem("token"),e.split("#")[0]);console.log("base_url",e),window.location="".concat(e,"#/login")}function a(){var e=window.location.href,e=(localStorage.removeItem("token"),e.split("#")[0]);window.location="".concat(e,"#/register")}function o(e){for(var t="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",n="",a=0;a>>0,a;for(a=0;a0)for(n=0;n=0;return(o?n?"+":"":"-")+Math.pow(10,Math.max(0,r)).toString().substr(1)+a}var ie=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,se=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,le={},ue={};function a(e,t,n,a){var r=a;if(typeof a==="string")r=function(){return this[a]()};if(e)ue[e]=r;if(t)ue[t[0]]=function(){return o(r.apply(this,arguments),t[1],t[2])};if(n)ue[n]=function(){return this.localeData().ordinal(r.apply(this,arguments),e)}}function ce(e){if(e.match(/\[[\s\S]/))return e.replace(/^\[|\]$/g,"");return e.replace(/\\/g,"")}function de(a){var r=a.match(ie),e,o;for(e=0,o=r.length;e=0&&se.test(e)){e=e.replace(se,a);se.lastIndex=0;n-=1}return e}var he={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"};function me(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];if(t||!n)return t;this._longDateFormat[e]=n.match(ie).map(function(e){if(e==="MMMM"||e==="MM"||e==="DD"||e==="dddd")return e.slice(1);return e}).join("");return this._longDateFormat[e]}var ge="Invalid date";function ye(){return this._invalidDate}var ve="%d",_e=/\d{1,2}/;function be(e){return this._ordinal.replace("%d",e)}var we={future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"};function Me(e,t,n,a){var r=this._relativeTime[n];return h(r)?r(e,t,n,a):r.replace(/%d/i,e)}function ke(e,t){var n=this._relativeTime[e>0?"future":"past"];return h(n)?n(t):n.replace(/%s/i,t)}var Se={};function t(e,t){var n=e.toLowerCase();Se[n]=Se[n+"s"]=Se[t]=e}function m(e){return typeof e==="string"?Se[e]||Se[e.toLowerCase()]:undefined}function Ee(e){var t={},n,a;for(a in e)if(l(e,a)){n=m(a);if(n)t[n]=e[a]}return t}var xe={};function n(e,t){xe[e]=t}function Ce(e){var t=[],n;for(n in e)if(l(e,n))t.push({unit:n,priority:xe[n]});t.sort(function(e,t){return e.priority-t.priority});return t}function Te(e){return e%4===0&&e%100!==0||e%400===0}function g(e){if(e<0)return Math.ceil(e)||0;else return Math.floor(e)}function y(e){var t=+e,n=0;if(t!==0&&isFinite(t))n=g(t);return n}function Le(t,n){return function(e){if(e!=null){De(this,t,e);d.updateOffset(this,n);return this}else return Oe(this,t)}}function Oe(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function De(e,t,n){if(e.isValid()&&!isNaN(n))if(t==="FullYear"&&Te(e.year())&&e.month()===1&&e.date()===29){n=y(n);e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),ot(n,e.month()))}else e._d["set"+(e._isUTC?"UTC":"")+t](n)}function Ne(e){e=m(e);if(h(this[e]))return this[e]();return this}function Pe(e,t){if(typeof e==="object"){e=Ee(e);var n=Ce(e),a,r=n.length;for(a=0;a68?1900:2e3)};var Mt=Le("FullYear",true);function kt(){return Te(this.year())}function St(e,t,n,a,r,o,i){var s;if(e<100&&e>=0){s=new Date(e+400,t,n,a,r,o,i);if(isFinite(s.getFullYear()))s.setFullYear(e)}else s=new Date(e,t,n,a,r,o,i);return s}function Et(e){var t,n;if(e<100&&e>=0){n=Array.prototype.slice.call(arguments);n[0]=e+400;t=new Date(Date.UTC.apply(null,n));if(isFinite(t.getUTCFullYear()))t.setUTCFullYear(e)}else t=new Date(Date.UTC.apply(null,arguments));return t}function xt(e,t,n){var a=7+t-n,r=(7+Et(e,0,a).getUTCDay()-t)%7;return-r+a-1}function Ct(e,t,n,a,r){var o=(7+n-a)%7,i=xt(e,a,r),s=1+7*(t-1)+o+i,l,u;if(s<=0){l=e-1;u=wt(l)+s}else if(s>wt(e)){l=e+1;u=s-wt(e)}else{l=e;u=s}return{year:l,dayOfYear:u}}function Tt(e,t,n){var a=xt(e.year(),t,n),r=Math.floor((e.dayOfYear()-a-1)/7)+1,o,i;if(r<1){i=e.year()-1;o=r+L(i,t,n)}else if(r>L(e.year(),t,n)){o=r-L(e.year(),t,n);i=e.year()+1}else{i=e.year();o=r}return{week:o,year:i}}function L(e,t,n){var a=xt(e,t,n),r=xt(e+1,t,n);return(wt(e)-a+r)/7}function Lt(e){return Tt(e,this._week.dow,this._week.doy).week}a("w",["ww",2],"wo","week"),a("W",["WW",2],"Wo","isoWeek"),t("week","w"),t("isoWeek","W"),n("week",5),n("isoWeek",5),_("w",v),_("ww",v,r),_("W",v),_("WW",v,r),Ze(["w","ww","W","WW"],function(e,t,n,a){t[a.substr(0,1)]=y(e)});var Ot={dow:0,doy:6};function Dt(){return this._week.dow}function Nt(){return this._week.doy}function Pt(e){var t=this.localeData().week(this);return e==null?t:this.add((e-t)*7,"d")}function jt(e){var t=Tt(this,1,4).week;return e==null?t:this.add((e-t)*7,"d")}function Yt(e,t){if(typeof e!=="string")return e;if(!isNaN(e))return parseInt(e,10);e=t.weekdaysParse(e);if(typeof e==="number")return e;return null}function It(e,t){if(typeof e==="string")return t.weekdaysParse(e)%7||7;return isNaN(e)?null:e}function At(e,t){return e.slice(t,7).concat(e.slice(0,t))}a("d",0,"do","day"),a("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),a("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),a("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),a("e",0,0,"weekday"),a("E",0,0,"isoWeekday"),t("day","d"),t("weekday","e"),t("isoWeekday","E"),n("day",11),n("weekday",11),n("isoWeekday",11),_("d",v),_("e",v),_("E",v),_("dd",function(e,t){return t.weekdaysMinRegex(e)}),_("ddd",function(e,t){return t.weekdaysShortRegex(e)}),_("dddd",function(e,t){return t.weekdaysRegex(e)}),Ze(["dd","ddd","dddd"],function(e,t,n,a){var r=n._locale.weekdaysParse(e,a,n._strict);if(r!=null)t.d=r;else f(n).invalidWeekday=e}),Ze(["d","e","E"],function(e,t,n,a){t[a]=y(e)});var Rt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Ht="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Ft="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),zt=Ge,Wt=Ge,Bt=Ge;function Ut(e,t){var n=i(this._weekdays)?this._weekdays:this._weekdays[e&&e!==true&&this._weekdays.isFormat.test(t)?"format":"standalone"];return e===true?At(n,this._week.dow):e?n[e.day()]:n}function Vt(e){return e===true?At(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort}function Kt(e){return e===true?At(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin}function qt(e,t,n){var a,r,o,i=e.toLocaleLowerCase();if(!this._weekdaysParse){this._weekdaysParse=[];this._shortWeekdaysParse=[];this._minWeekdaysParse=[];for(a=0;a<7;++a){o=c([2e3,1]).day(a);this._minWeekdaysParse[a]=this.weekdaysMin(o,"").toLocaleLowerCase();this._shortWeekdaysParse[a]=this.weekdaysShort(o,"").toLocaleLowerCase();this._weekdaysParse[a]=this.weekdays(o,"").toLocaleLowerCase()}}if(n)if(t==="dddd"){r=T.call(this._weekdaysParse,i);return r!==-1?r:null}else if(t==="ddd"){r=T.call(this._shortWeekdaysParse,i);return r!==-1?r:null}else{r=T.call(this._minWeekdaysParse,i);return r!==-1?r:null}else if(t==="dddd"){r=T.call(this._weekdaysParse,i);if(r!==-1)return r;r=T.call(this._shortWeekdaysParse,i);if(r!==-1)return r;r=T.call(this._minWeekdaysParse,i);return r!==-1?r:null}else if(t==="ddd"){r=T.call(this._shortWeekdaysParse,i);if(r!==-1)return r;r=T.call(this._weekdaysParse,i);if(r!==-1)return r;r=T.call(this._minWeekdaysParse,i);return r!==-1?r:null}else{r=T.call(this._minWeekdaysParse,i);if(r!==-1)return r;r=T.call(this._weekdaysParse,i);if(r!==-1)return r;r=T.call(this._shortWeekdaysParse,i);return r!==-1?r:null}}function Gt(e,t,n){var a,r,o;if(this._weekdaysParseExact)return qt.call(this,e,t,n);if(!this._weekdaysParse){this._weekdaysParse=[];this._minWeekdaysParse=[];this._shortWeekdaysParse=[];this._fullWeekdaysParse=[]}for(a=0;a<7;a++){r=c([2e3,1]).day(a);if(n&&!this._fullWeekdaysParse[a]){this._fullWeekdaysParse[a]=new RegExp("^"+this.weekdays(r,"").replace(".","\\.?")+"$","i");this._shortWeekdaysParse[a]=new RegExp("^"+this.weekdaysShort(r,"").replace(".","\\.?")+"$","i");this._minWeekdaysParse[a]=new RegExp("^"+this.weekdaysMin(r,"").replace(".","\\.?")+"$","i")}if(!this._weekdaysParse[a]){o="^"+this.weekdays(r,"")+"|^"+this.weekdaysShort(r,"")+"|^"+this.weekdaysMin(r,"");this._weekdaysParse[a]=new RegExp(o.replace(".",""),"i")}if(n&&t==="dddd"&&this._fullWeekdaysParse[a].test(e))return a;else if(n&&t==="ddd"&&this._shortWeekdaysParse[a].test(e))return a;else if(n&&t==="dd"&&this._minWeekdaysParse[a].test(e))return a;else if(!n&&this._weekdaysParse[a].test(e))return a}}function $t(e){if(!this.isValid())return e!=null?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();if(e!=null){e=Yt(e,this.localeData());return this.add(e-t,"d")}else return t}function Jt(e){if(!this.isValid())return e!=null?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return e==null?t:this.add(e-t,"d")}function Qt(e){if(!this.isValid())return e!=null?this:NaN;if(e!=null){var t=It(e,this.localeData());return this.day(this.day()%7?t:t-7)}else return this.day()||7}function Xt(e){if(this._weekdaysParseExact){if(!l(this,"_weekdaysRegex"))tn.call(this);if(e)return this._weekdaysStrictRegex;else return this._weekdaysRegex}else{if(!l(this,"_weekdaysRegex"))this._weekdaysRegex=zt;return this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex}}function Zt(e){if(this._weekdaysParseExact){if(!l(this,"_weekdaysRegex"))tn.call(this);if(e)return this._weekdaysShortStrictRegex;else return this._weekdaysShortRegex}else{if(!l(this,"_weekdaysShortRegex"))this._weekdaysShortRegex=Wt;return this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}}function en(e){if(this._weekdaysParseExact){if(!l(this,"_weekdaysRegex"))tn.call(this);if(e)return this._weekdaysMinStrictRegex;else return this._weekdaysMinRegex}else{if(!l(this,"_weekdaysMinRegex"))this._weekdaysMinRegex=Bt;return this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}}function tn(){function e(e,t){return t.length-e.length}var t=[],n=[],a=[],r=[],o,i,s,l,u;for(o=0;o<7;o++){i=c([2e3,1]).day(o);s=b(this.weekdaysMin(i,""));l=b(this.weekdaysShort(i,""));u=b(this.weekdays(i,""));t.push(s);n.push(l);a.push(u);r.push(s);r.push(l);r.push(u)}t.sort(e);n.sort(e);a.sort(e);r.sort(e);this._weekdaysRegex=new RegExp("^("+r.join("|")+")","i");this._weekdaysShortRegex=this._weekdaysRegex;this._weekdaysMinRegex=this._weekdaysRegex;this._weekdaysStrictRegex=new RegExp("^("+a.join("|")+")","i");this._weekdaysShortStrictRegex=new RegExp("^("+n.join("|")+")","i");this._weekdaysMinStrictRegex=new RegExp("^("+t.join("|")+")","i")}function nn(){return this.hours()%12||12}function an(){return this.hours()||24}function rn(e,t){a(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function on(e,t){return t._meridiemParse}function sn(e){return(e+"").toLowerCase().charAt(0)==="p"}a("H",["HH",2],0,"hour"),a("h",["hh",2],0,nn),a("k",["kk",2],0,an),a("hmm",0,0,function(){return""+nn.apply(this)+o(this.minutes(),2)}),a("hmmss",0,0,function(){return""+nn.apply(this)+o(this.minutes(),2)+o(this.seconds(),2)}),a("Hmm",0,0,function(){return""+this.hours()+o(this.minutes(),2)}),a("Hmmss",0,0,function(){return""+this.hours()+o(this.minutes(),2)+o(this.seconds(),2)}),rn("a",true),rn("A",false),t("hour","h"),n("hour",13),_("a",on),_("A",on),_("H",v),_("h",v),_("k",v),_("HH",v,r),_("hh",v,r),_("kk",v,r),_("hmm",Re),_("hmmss",He),_("Hmm",Re),_("Hmmss",He),w(["H","HH"],E),w(["k","kk"],function(e,t,n){var a=y(e);t[E]=a===24?0:a}),w(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e);n._meridiem=e}),w(["h","hh"],function(e,t,n){t[E]=y(e);f(n).bigHour=true}),w("hmm",function(e,t,n){var a=e.length-2;t[E]=y(e.substr(0,a));t[x]=y(e.substr(a));f(n).bigHour=true}),w("hmmss",function(e,t,n){var a=e.length-4,r=e.length-2;t[E]=y(e.substr(0,a));t[x]=y(e.substr(a,2));t[C]=y(e.substr(r));f(n).bigHour=true}),w("Hmm",function(e,t,n){var a=e.length-2;t[E]=y(e.substr(0,a));t[x]=y(e.substr(a))}),w("Hmmss",function(e,t,n){var a=e.length-4,r=e.length-2;t[E]=y(e.substr(0,a));t[x]=y(e.substr(a,2));t[C]=y(e.substr(r))});var ln,un=Le("Hours",true);function cn(e,t,n){if(e>11)return n?"pm":"PM";else return n?"am":"AM"}var dn={calendar:re,longDateFormat:he,invalidDate:ge,ordinal:ve,dayOfMonthOrdinalParse:_e,relativeTime:we,months:it,monthsShort:st,week:Ot,weekdays:Rt,weekdaysMin:Ft,weekdaysShort:Ht,meridiemParse:/[ap]\.?m?\.?/i},O={},fn={},pn;function hn(e,t){var n,a=Math.min(e.length,t.length);for(n=0;n0){r=vn(o.slice(0,n).join("-"));if(r)return r;if(a&&a.length>=n&&hn(o,a)>=n-1)break;n--}t++}return pn}function yn(e){return e.match("^[^/\\\\]*$")!=null}function vn(t){var e=null,n;if(O[t]===undefined&&typeof ci!=="undefined"&&ci&&ci.exports&&yn(t))try{e=pn._abbr;n=di;fi(536)("./"+t);_n(e)}catch(e){O[t]=null}return O[t]}function _n(e,t){var n;if(e){if(s(t))n=Mn(e);else n=bn(e,t);if(n)pn=n;else if(typeof console!=="undefined"&&console.warn)console.warn("Locale "+e+" not found. Did you forget to load it?")}return pn._abbr}function bn(e,t){if(t!==null){var n,a=dn;t.abbr=e;if(O[e]!=null){ee("defineLocaleOverride","use moment.updateLocale(localeName, config) to change "+"an existing locale. moment.defineLocale(localeName, "+"config) should only be used for creating a new locale "+"See http://momentjs.com/guides/#/warnings/define-locale/ for more info.");a=O[e]._config}else if(t.parentLocale!=null)if(O[t.parentLocale]!=null)a=O[t.parentLocale]._config;else{n=vn(t.parentLocale);if(n!=null)a=n._config;else{if(!fn[t.parentLocale])fn[t.parentLocale]=[];fn[t.parentLocale].push({name:e,config:t});return null}}O[e]=new ae(ne(a,t));if(fn[e])fn[e].forEach(function(e){bn(e.name,e.config)});_n(e);return O[e]}else{delete O[e];return null}}function wn(e,t){if(t!=null){var n,a,r=dn;if(O[e]!=null&&O[e].parentLocale!=null)O[e].set(ne(O[e]._config,t));else{a=vn(e);if(a!=null)r=a._config;t=ne(r,t);if(a==null)t.abbr=e;n=new ae(t);n.parentLocale=O[e];O[e]=n}_n(e)}else if(O[e]!=null)if(O[e].parentLocale!=null){O[e]=O[e].parentLocale;if(e===_n())_n(e)}else if(O[e]!=null)delete O[e];return O[e]}function Mn(e){var t;if(e&&e._locale&&e._locale._abbr)e=e._locale._abbr;if(!e)return pn;if(!i(e)){t=vn(e);if(t)return t;e=[e]}return gn(e)}function kn(){return Z(O)}function Sn(e){var t,n=e._a;if(n&&f(e).overflow===-2){t=n[k]<0||n[k]>11?k:n[S]<1||n[S]>ot(n[M],n[k])?S:n[E]<0||n[E]>24||n[E]===24&&(n[x]!==0||n[C]!==0||n[tt]!==0)?E:n[x]<0||n[x]>59?x:n[C]<0||n[C]>59?C:n[tt]<0||n[tt]>999?tt:-1;if(f(e)._overflowDayOfYear&&(tS))t=S;if(f(e)._overflowWeeks&&t===-1)t=nt;if(f(e)._overflowWeekday&&t===-1)t=at;f(e).overflow=t}return e}var En=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,xn=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,Cn=/Z|[+-]\d\d(?::?\d\d)?/,Tn=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,false],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,false],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,false],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,false],["YYYY",/\d{4}/,false]],Ln=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],On=/^\/?Date\((-?\d+)/i,Dn=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,Nn={UT:0,GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60};function Pn(e){var t,n,a=e._i,r=En.exec(a)||xn.exec(a),o,i,s,l,u=Tn.length,c=Ln.length;if(r){f(e).iso=true;for(t=0,n=u;twt(i)||e._dayOfYear===0)f(e)._overflowDayOfYear=true;n=Et(i,0,e._dayOfYear);e._a[k]=n.getUTCMonth();e._a[S]=n.getUTCDate()}for(t=0;t<3&&e._a[t]==null;++t)e._a[t]=a[t]=r[t];for(;t<7;t++)e._a[t]=a[t]=e._a[t]==null?t===2?1:0:e._a[t];if(e._a[E]===24&&e._a[x]===0&&e._a[C]===0&&e._a[tt]===0){e._nextDay=true;e._a[E]=0}e._d=(e._useUTC?Et:St).apply(null,a);o=e._useUTC?e._d.getUTCDay():e._d.getDay();if(e._tzm!=null)e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm);if(e._nextDay)e._a[E]=24;if(e._w&&typeof e._w.d!=="undefined"&&e._w.d!==o)f(e).weekdayMismatch=true}function Un(e){var t,n,a,r,o,i,s,l,u;t=e._w;if(t.GG!=null||t.W!=null||t.E!=null){o=1;i=4;n=zn(t.GG,e._a[M],Tt(D(),1,4).year);a=zn(t.W,1);r=zn(t.E,1);if(r<1||r>7)l=true}else{o=e._locale._week.dow;i=e._locale._week.doy;u=Tt(D(),o,i);n=zn(t.gg,e._a[M],u.year);a=zn(t.w,u.week);if(t.d!=null){r=t.d;if(r<0||r>6)l=true}else if(t.e!=null){r=t.e+o;if(t.e<0||t.e>6)l=true}else r=o}if(a<1||a>L(n,o,i))f(e)._overflowWeeks=true;else if(l!=null)f(e)._overflowWeekday=true;else{s=Ct(n,a,r,o,i);e._a[M]=s.year;e._dayOfYear=s.dayOfYear}}function Vn(e){if(e._f===d.ISO_8601){Pn(e);return}if(e._f===d.RFC_2822){Hn(e);return}e._a=[];f(e).empty=true;var t=""+e._i,n,a,r,o,i,s=t.length,l=0,u,c;r=pe(e._f,e._locale).match(ie)||[];c=r.length;for(n=0;n0)f(e).unusedInput.push(i);t=t.slice(t.indexOf(a)+a.length);l+=a.length}if(ue[o]){if(a)f(e).empty=false;else f(e).unusedTokens.push(o);et(o,a,e)}else if(e._strict&&!a)f(e).unusedTokens.push(o)}f(e).charsLeftOver=s-l;if(t.length>0)f(e).unusedInput.push(t);if(e._a[E]<=12&&f(e).bigHour===true&&e._a[E]>0)f(e).bigHour=undefined;f(e).parsedDateParts=e._a.slice(0);f(e).meridiem=e._meridiem;e._a[E]=Kn(e._locale,e._a[E],e._meridiem);u=f(e).era;if(u!==null)e._a[M]=e._locale.erasConvertYear(u,e._a[M]);Bn(e);Sn(e)}function Kn(e,t,n){var a;if(n==null)return t;if(e.meridiemHour!=null)return e.meridiemHour(t,n);else if(e.isPM!=null){a=e.isPM(n);if(a&&t<12)t+=12;if(!a&&t===12)t=0;return t}else return t}function qn(e){var t,n,a,r,o,i,s=false,l=e._f.length;if(l===0){f(e).invalidFormat=true;e._d=new Date(NaN);return}for(r=0;rthis?this:e;else return K()});function ta(e,t){var n,a;if(t.length===1&&i(t[0]))t=t[0];if(!t.length)return D();n=t[0];for(a=1;athis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Ea(){if(!s(this._isDSTShifted))return this._isDSTShifted;var e={},t;$(e,this);e=Jn(e);if(e._a){t=e._isUTC?c(e._a):D(e._a);this._isDSTShifted=this.isValid()&&fa(e._a,t.toArray())>0}else this._isDSTShifted=false;return this._isDSTShifted}function xa(){return this.isValid()?!this._isUTC:false}function Ca(){return this.isValid()?this._isUTC:false}function Ta(){return this.isValid()?this._isUTC&&this._offset===0:false}d.updateOffset=function(){};var La=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,Oa=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function N(e,t){var n=e,a=null,r,o,i;if(ca(e))n={ms:e._milliseconds,d:e._days,M:e._months};else if(u(e)||!isNaN(+e)){n={};if(t)n[t]=+e;else n.milliseconds=+e}else if(a=La.exec(e)){r=a[1]==="-"?-1:1;n={y:0,d:y(a[S])*r,h:y(a[E])*r,m:y(a[x])*r,s:y(a[C])*r,ms:y(da(a[tt]*1e3))*r}}else if(a=Oa.exec(e)){r=a[1]==="-"?-1:1;n={y:Da(a[2],r),M:Da(a[3],r),w:Da(a[4],r),d:Da(a[5],r),h:Da(a[6],r),m:Da(a[7],r),s:Da(a[8],r)}}else if(n==null)n={};else if(typeof n==="object"&&("from"in n||"to"in n)){i=Pa(D(n.from),D(n.to));n={};n.ms=i.milliseconds;n.M=i.months}o=new ua(n);if(ca(e)&&l(e,"_locale"))o._locale=e._locale;if(ca(e)&&l(e,"_isValid"))o._isValid=e._isValid;return o}function Da(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function Na(e,t){var n={};n.months=t.month()-e.month()+(t.year()-e.year())*12;if(e.clone().add(n.months,"M").isAfter(t))--n.months;n.milliseconds=+t-+e.clone().add(n.months,"M");return n}function Pa(e,t){var n;if(!(e.isValid()&&t.isValid()))return{milliseconds:0,months:0};t=ga(t,e);if(e.isBefore(t))n=Na(e,t);else{n=Na(t,e);n.milliseconds=-n.milliseconds;n.months=-n.months}return n}function ja(r,o){return function(e,t){var n,a;if(t!==null&&!isNaN(+t)){ee(o,"moment()."+o+"(period, number) is deprecated. Please use moment()."+o+"(number, period). "+"See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.");a=e;e=t;t=a}n=N(e,t);Ya(this,n,r);return this}}function Ya(e,t,n,a){var r=t._milliseconds,o=da(t._days),i=da(t._months);if(!e.isValid())return;a=a==null?true:a;if(i)mt(e,Oe(e,"Month")+i*n);if(o)De(e,"Date",Oe(e,"Date")+o*n);if(r)e._d.setTime(e._d.valueOf()+r*n);if(a)d.updateOffset(e,o||i)}N.fn=ua.prototype,N.invalid=la;var Ia=ja(1,"add"),Aa=ja(-1,"subtract");function Ra(e){return typeof e==="string"||e instanceof String}function Ha(e){return p(e)||z(e)||Ra(e)||u(e)||za(e)||Fa(e)||e===null||e===undefined}function Fa(e){var t=H(e)&&!F(e),n=false,a=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"],r,o,i=a.length;for(r=0;rn.valueOf();else return n.valueOf()9999)return fe(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ");if(h(Date.prototype.toISOString))if(t)return this.toDate().toISOString();else return new Date(this.valueOf()+this.utcOffset()*60*1e3).toISOString().replace("Z",fe(n,"Z"));return fe(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")}function nr(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="",n,a,r,o;if(!this.isLocal()){e=this.utcOffset()===0?"moment.utc":"moment.parseZone";t="Z"}n="["+e+'("]';a=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY";r="-MM-DD[T]HH:mm:ss.SSS";o=t+'[")]';return this.format(n+a+r+o)}function ar(e){if(!e)e=this.isUtc()?d.defaultFormatUtc:d.defaultFormat;var t=fe(this,e);return this.localeData().postformat(t)}function rr(e,t){if(this.isValid()&&(p(e)&&e.isValid()||D(e).isValid()))return N({to:this,from:e}).locale(this.locale()).humanize(!t);else return this.localeData().invalidDate()}function or(e){return this.from(D(),e)}function ir(e,t){if(this.isValid()&&(p(e)&&e.isValid()||D(e).isValid()))return N({from:this,to:e}).locale(this.locale()).humanize(!t);else return this.localeData().invalidDate()}function sr(e){return this.to(D(),e)}function lr(e){var t;if(e===undefined)return this._locale._abbr;else{t=Mn(e);if(t!=null)this._locale=t;return this}}d.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",d.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ur=e("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){if(e===undefined)return this.localeData();else return this.locale(e)});function cr(){return this._locale}var dr=1e3,fr=60*dr,pr=60*fr,hr=(365*400+97)*24*pr;function mr(e,t){return(e%t+t)%t}function gr(e,t,n){if(e<100&&e>=0)return new Date(e+400,t,n)-hr;else return new Date(e,t,n).valueOf()}function yr(e,t,n){if(e<100&&e>=0)return Date.UTC(e+400,t,n)-hr;else return Date.UTC(e,t,n)}function vr(e){var t,n;e=m(e);if(e===undefined||e==="millisecond"||!this.isValid())return this;n=this._isUTC?yr:gr;switch(e){case"year":t=n(this.year(),0,1);break;case"quarter":t=n(this.year(),this.month()-this.month()%3,1);break;case"month":t=n(this.year(),this.month(),1);break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":t=n(this.year(),this.month(),this.date());break;case"hour":t=this._d.valueOf();t-=mr(t+(this._isUTC?0:this.utcOffset()*fr),pr);break;case"minute":t=this._d.valueOf();t-=mr(t,fr);break;case"second":t=this._d.valueOf();t-=mr(t,dr);break}this._d.setTime(t);d.updateOffset(this,true);return this}function _r(e){var t,n;e=m(e);if(e===undefined||e==="millisecond"||!this.isValid())return this;n=this._isUTC?yr:gr;switch(e){case"year":t=n(this.year()+1,0,1)-1;break;case"quarter":t=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":t=n(this.year(),this.month()+1,1)-1;break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":t=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":t=this._d.valueOf();t+=pr-mr(t+(this._isUTC?0:this.utcOffset()*fr),pr)-1;break;case"minute":t=this._d.valueOf();t+=fr-mr(t,fr)-1;break;case"second":t=this._d.valueOf();t+=dr-mr(t,dr)-1;break}this._d.setTime(t);d.updateOffset(this,true);return this}function br(){return this._d.valueOf()-(this._offset||0)*6e4}function wr(){return Math.floor(this.valueOf()/1e3)}function Mr(){return new Date(this.valueOf())}function kr(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]}function Sr(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}}function Er(){return this.isValid()?this.toISOString():null}function xr(){return V(this)}function Cr(){return B({},f(this))}function Tr(){return f(this).overflow}function Lr(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Or(e,t){var n,a,r,o=this._eras||Mn("en")._eras;for(n=0,a=o.length;n=0)return o[a]}}function Nr(e,t){var n=e.since<=e.until?+1:-1;if(t===undefined)return d(e.since).year();else return d(e.since).year()+(t-e.offset)*n}function Pr(){var e,t,n,a=this.localeData().eras();for(e=0,t=a.length;eo)t=o;return Zr.call(this,e,t,n,a,r)}}function Zr(e,t,n,a,r){var o=Ct(e,t,n,a,r),i=Et(o.year,0,o.dayOfYear);this.year(i.getUTCFullYear());this.month(i.getUTCMonth());this.date(i.getUTCDate());return this}function eo(e){return e==null?Math.ceil((this.month()+1)/3):this.month((e-1)*3+this.month()%3)}a("N",0,0,"eraAbbr"),a("NN",0,0,"eraAbbr"),a("NNN",0,0,"eraAbbr"),a("NNNN",0,0,"eraName"),a("NNNNN",0,0,"eraNarrow"),a("y",["y",1],"yo","eraYear"),a("y",["yy",2],0,"eraYear"),a("y",["yyy",3],0,"eraYear"),a("y",["yyyy",4],0,"eraYear"),_("N",Fr),_("NN",Fr),_("NNN",Fr),_("NNNN",zr),_("NNNNN",Wr),w(["N","NN","NNN","NNNN","NNNNN"],function(e,t,n,a){var r=n._locale.erasParse(e,a,n._strict);if(r)f(n).era=r;else f(n).invalidEra=e}),_("y",Be),_("yy",Be),_("yyy",Be),_("yyyy",Be),_("yo",Br),w(["y","yy","yyy","yyyy"],M),w(["yo"],function(e,t,n,a){var r;if(n._locale._eraYearOrdinalRegex)r=e.match(n._locale._eraYearOrdinalRegex);if(n._locale.eraYearOrdinalParse)t[M]=n._locale.eraYearOrdinalParse(e,r);else t[M]=parseInt(e,10)}),a(0,["gg",2],0,function(){return this.weekYear()%100}),a(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Vr("gggg","weekYear"),Vr("ggggg","weekYear"),Vr("GGGG","isoWeekYear"),Vr("GGGGG","isoWeekYear"),t("weekYear","gg"),t("isoWeekYear","GG"),n("weekYear",1),n("isoWeekYear",1),_("G",Ue),_("g",Ue),_("GG",v,r),_("gg",v,r),_("GGGG",ze,Ie),_("gggg",ze,Ie),_("GGGGG",We,Ae),_("ggggg",We,Ae),Ze(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,a){t[a.substr(0,2)]=y(e)}),Ze(["gg","GG"],function(e,t,n,a){t[a]=d.parseTwoDigitYear(e)}),a("Q",0,"Qo","quarter"),t("quarter","Q"),n("quarter",7),_("Q",je),w("Q",function(e,t){t[k]=(y(e)-1)*3}),a("D",["DD",2],"Do","date"),t("date","D"),n("date",9),_("D",v),_("DD",v,r),_("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),w(["D","DD"],S),w("Do",function(e,t){t[S]=y(e.match(v)[0])});var to=Le("Date",true);function no(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return e==null?t:this.add(e-t,"d")}a("DDD",["DDDD",3],"DDDo","dayOfYear"),t("dayOfYear","DDD"),n("dayOfYear",4),_("DDD",Fe),_("DDDD",Ye),w(["DDD","DDDD"],function(e,t,n){n._dayOfYear=y(e)}),a("m",["mm",2],0,"minute"),t("minute","m"),n("minute",14),_("m",v),_("mm",v,r),w(["m","mm"],x);var ao=Le("Minutes",false),ro=(a("s",["ss",2],0,"second"),t("second","s"),n("second",15),_("s",v),_("ss",v,r),w(["s","ss"],C),Le("Seconds",false)),oo,io;for(a("S",0,0,function(){return~~(this.millisecond()/100)}),a(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),a(0,["SSS",3],0,"millisecond"),a(0,["SSSS",4],0,function(){return this.millisecond()*10}),a(0,["SSSSS",5],0,function(){return this.millisecond()*100}),a(0,["SSSSSS",6],0,function(){return this.millisecond()*1e3}),a(0,["SSSSSSS",7],0,function(){return this.millisecond()*1e4}),a(0,["SSSSSSSS",8],0,function(){return this.millisecond()*1e5}),a(0,["SSSSSSSSS",9],0,function(){return this.millisecond()*1e6}),t("millisecond","ms"),n("millisecond",16),_("S",Fe,je),_("SS",Fe,r),_("SSS",Fe,Ye),oo="SSSS";oo.length<=9;oo+="S")_(oo,Be);function so(e,t){t[tt]=y(("0."+e)*1e3)}for(oo="S";oo.length<=9;oo+="S")w(oo,so);function lo(){return this._isUTC?"UTC":""}function uo(){return this._isUTC?"Coordinated Universal Time":""}io=Le("Milliseconds",false),a("z",0,0,"zoneAbbr"),a("zz",0,0,"zoneName");var P=J.prototype;if(P.add=Ia,P.calendar=Ua,P.clone=Va,P.diff=Xa,P.endOf=_r,P.format=ar,P.from=rr,P.fromNow=or,P.to=ir,P.toNow=sr,P.get=Ne,P.invalidAt=Tr,P.isAfter=Ka,P.isBefore=qa,P.isBetween=Ga,P.isSame=$a,P.isSameOrAfter=Ja,P.isSameOrBefore=Qa,P.isValid=xr,P.lang=ur,P.locale=lr,P.localeData=cr,P.max=ea,P.min=Zn,P.parsingFlags=Cr,P.set=Pe,P.startOf=vr,P.subtract=Aa,P.toArray=kr,P.toObject=Sr,P.toDate=Mr,P.toISOString=tr,P.inspect=nr,typeof Symbol!=="undefined"&&Symbol.for!=null)P[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"};function co(e){return D(e*1e3)}function fo(){return D.apply(null,arguments).parseZone()}function po(e){return e}P.toJSON=Er,P.toString=er,P.unix=wr,P.valueOf=br,P.creationData=Lr,P.eraName=Pr,P.eraNarrow=jr,P.eraAbbr=Yr,P.eraYear=Ir,P.year=Mt,P.isLeapYear=kt,P.weekYear=Kr,P.isoWeekYear=qr,P.quarter=P.quarters=eo,P.month=gt,P.daysInMonth=yt,P.week=P.weeks=Pt,P.isoWeek=P.isoWeeks=jt,P.weeksInYear=Jr,P.weeksInWeekYear=Qr,P.isoWeeksInYear=Gr,P.isoWeeksInISOWeekYear=$r,P.date=to,P.day=P.days=$t,P.weekday=Jt,P.isoWeekday=Qt,P.dayOfYear=no,P.hour=P.hours=un,P.minute=P.minutes=ao,P.second=P.seconds=ro,P.millisecond=P.milliseconds=io,P.utcOffset=va,P.utc=ba,P.local=wa,P.parseZone=Ma,P.hasAlignedHourOffset=ka,P.isDST=Sa,P.isLocal=xa,P.isUtcOffset=Ca,P.isUtc=Ta,P.isUTC=Ta,P.zoneAbbr=lo,P.zoneName=uo,P.dates=e("dates accessor is deprecated. Use date instead.",to),P.months=e("months accessor is deprecated. Use month instead",gt),P.years=e("years accessor is deprecated. Use year instead",Mt),P.zone=e("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",_a),P.isDSTShifted=e("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",Ea);var j=ae.prototype;function ho(e,t,n,a){var r=Mn(),o=c().set(a,t);return r[n](o,e)}function mo(e,t,n){if(u(e)){t=e;e=undefined}e=e||"";if(t!=null)return ho(e,t,n,"month");var a,r=[];for(a=0;a<12;a++)r[a]=ho(e,a,n,"month");return r}function go(e,t,n,a){if(typeof e==="boolean"){if(u(t)){n=t;t=undefined}t=t||""}else{t=e;n=t;e=false;if(u(t)){n=t;t=undefined}t=t||""}var r=Mn(),o=e?r._week.dow:0,i,s=[];if(n!=null)return ho(t,(n+o)%7,a,"day");for(i=0;i<7;i++)s[i]=ho(t,(i+o)%7,a,"day");return s}function yo(e,t){return mo(e,t,"months")}function vo(e,t){return mo(e,t,"monthsShort")}function _o(e,t,n){return go(e,t,n,"weekdays")}function bo(e,t,n){return go(e,t,n,"weekdaysShort")}function wo(e,t,n){return go(e,t,n,"weekdaysMin")}j.calendar=oe,j.longDateFormat=me,j.invalidDate=ye,j.ordinal=be,j.preparse=po,j.postformat=po,j.relativeTime=Me,j.pastFuture=ke,j.set=te,j.eras=Or,j.erasParse=Dr,j.erasConvertYear=Nr,j.erasAbbrRegex=Rr,j.erasNameRegex=Ar,j.erasNarrowRegex=Hr,j.months=dt,j.monthsShort=ft,j.monthsParse=ht,j.monthsRegex=_t,j.monthsShortRegex=vt,j.week=Lt,j.firstDayOfYear=Nt,j.firstDayOfWeek=Dt,j.weekdays=Ut,j.weekdaysMin=Kt,j.weekdaysShort=Vt,j.weekdaysParse=Gt,j.weekdaysRegex=Xt,j.weekdaysShortRegex=Zt,j.weekdaysMinRegex=en,j.isPM=sn,j.meridiem=cn,_n("en",{eras:[{since:"0001-01-01",until:+Infinity,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-Infinity,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10,n=y(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n}}),d.lang=e("moment.lang is deprecated. Use moment.locale instead.",_n),d.langData=e("moment.langData is deprecated. Use moment.localeData instead.",Mn);var Mo=Math.abs;function ko(){var e=this._data;this._milliseconds=Mo(this._milliseconds);this._days=Mo(this._days);this._months=Mo(this._months);e.milliseconds=Mo(e.milliseconds);e.seconds=Mo(e.seconds);e.minutes=Mo(e.minutes);e.hours=Mo(e.hours);e.months=Mo(e.months);e.years=Mo(e.years);return this}function So(e,t,n,a){var r=N(t,n);e._milliseconds+=a*r._milliseconds;e._days+=a*r._days;e._months+=a*r._months;return e._bubble()}function Eo(e,t){return So(this,e,t,1)}function xo(e,t){return So(this,e,t,-1)}function Co(e){if(e<0)return Math.floor(e);else return Math.ceil(e)}function To(){var e=this._milliseconds,t=this._days,n=this._months,a=this._data,r,o,i,s,l;if(!(e>=0&&t>=0&&n>=0||e<=0&&t<=0&&n<=0)){e+=Co(Oo(n)+t)*864e5;t=0;n=0}a.milliseconds=e%1e3;r=g(e/1e3);a.seconds=r%60;o=g(r/60);a.minutes=o%60;i=g(o/60);a.hours=i%24;t+=g(i/24);l=g(Lo(t));n+=l;t-=Co(Oo(l));s=g(n/12);n%=12;a.days=t;a.months=n;a.years=s;return this}function Lo(e){return e*4800/146097}function Oo(e){return e*146097/4800}function Do(e){if(!this.isValid())return NaN;var t,n,a=this._milliseconds;e=m(e);if(e==="month"||e==="quarter"||e==="year"){t=this._days+a/864e5;n=this._months+Lo(t);switch(e){case"month":return n;case"quarter":return n/3;case"year":return n/12}}else{t=this._days+Math.round(Oo(this._months));switch(e){case"week":return t/7+a/6048e5;case"day":return t+a/864e5;case"hour":return t*24+a/36e5;case"minute":return t*1440+a/6e4;case"second":return t*86400+a/1e3;case"millisecond":return Math.floor(t*864e5)+a;default:throw new Error("Unknown unit "+e)}}}function No(){if(!this.isValid())return NaN;return this._milliseconds+this._days*864e5+this._months%12*2592e6+y(this._months/12)*31536e6}function Po(e){return function(){return this.as(e)}}var jo=Po("ms"),Yo=Po("s"),Io=Po("m"),Ao=Po("h"),Ro=Po("d"),Ho=Po("w"),Fo=Po("M"),zo=Po("Q"),Wo=Po("y");function Bo(){return N(this)}function Uo(e){e=m(e);return this.isValid()?this[e+"s"]():NaN}function Vo(e){return function(){return this.isValid()?this._data[e]:NaN}}var Ko=Vo("milliseconds"),qo=Vo("seconds"),Go=Vo("minutes"),$o=Vo("hours"),Jo=Vo("days"),Qo=Vo("months"),Xo=Vo("years");function Zo(){return g(this.days()/7)}var ei=Math.round,ti={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function ni(e,t,n,a,r){return r.relativeTime(t||1,!!n,e,a)}function ai(e,t,n,a){var r=N(e).abs(),o=ei(r.as("s")),i=ei(r.as("m")),s=ei(r.as("h")),l=ei(r.as("d")),u=ei(r.as("M")),c=ei(r.as("w")),d=ei(r.as("y")),f=o<=n.ss&&["s",o]||o0;f[4]=a;return ni.apply(null,f)}function ri(e){if(e===undefined)return ei;if(typeof e==="function"){ei=e;return true}return false}function oi(e,t){if(ti[e]===undefined)return false;if(t===undefined)return ti[e];ti[e]=t;if(e==="s")ti.ss=t-1;return true}function ii(e,t){if(!this.isValid())return this.localeData().invalidDate();var n=false,a=ti,r,o;if(typeof e==="object"){t=e;e=false}if(typeof e==="boolean")n=e;if(typeof t==="object"){a=Object.assign({},ti,t);if(t.s!=null&&t.ss==null)a.ss=t.s-1}r=this.localeData();o=ai(this,!n,a,r);if(n)o=r.pastFuture(+this,o);return r.postformat(o)}var si=Math.abs;function li(e){return(e>0)-(e<0)||+e}function ui(){if(!this.isValid())return this.localeData().invalidDate();var e=si(this._milliseconds)/1e3,t=si(this._days),n=si(this._months),a,r,o,i,s=this.asSeconds(),l,u,c,d;if(!s)return"P0D";a=g(e/60);r=g(a/60);e%=60;a%=60;o=g(n/12);n%=12;i=e?e.toFixed(3).replace(/\.?0+$/,""):"";l=s<0?"-":"";u=li(this._months)!==li(s)?"-":"";c=li(this._days)!==li(s)?"-":"";d=li(this._milliseconds)!==li(s)?"-":"";return l+"P"+(o?u+o+"Y":"")+(n?u+n+"M":"")+(t?c+t+"D":"")+(r||a||e?"T":"")+(r?d+r+"H":"")+(a?d+a+"M":"")+(e?d+i+"S":"")}var Y=ua.prototype;return Y.isValid=sa,Y.abs=ko,Y.add=Eo,Y.subtract=xo,Y.as=Do,Y.asMilliseconds=jo,Y.asSeconds=Yo,Y.asMinutes=Io,Y.asHours=Ao,Y.asDays=Ro,Y.asWeeks=Ho,Y.asMonths=Fo,Y.asQuarters=zo,Y.asYears=Wo,Y.valueOf=No,Y._bubble=To,Y.clone=Bo,Y.get=Uo,Y.milliseconds=Ko,Y.seconds=qo,Y.minutes=Go,Y.hours=$o,Y.days=Jo,Y.weeks=Zo,Y.months=Qo,Y.years=Xo,Y.humanize=ii,Y.toISOString=ui,Y.toString=ui,Y.toJSON=ui,Y.locale=lr,Y.localeData=cr,Y.toIsoString=e("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ui),Y.lang=ur,a("X",0,0,"unix"),a("x",0,0,"valueOf"),_("x",Ue),_("X",qe),w("X",function(e,t,n){n._d=new Date(parseFloat(e)*1e3)}),w("x",function(e,t,n){n._d=new Date(y(e))}), +//! moment.js +d.version="2.29.4",R(D),d.fn=P,d.min=na,d.max=aa,d.now=ra,d.utc=c,d.unix=co,d.months=yo,d.isDate=z,d.locale=_n,d.invalid=K,d.duration=N,d.isMoment=p,d.weekdays=_o,d.parseZone=fo,d.localeData=Mn,d.isDuration=ca,d.monthsShort=vo,d.weekdaysMin=wo,d.defineLocale=bn,d.updateLocale=wn,d.locales=kn,d.weekdaysShort=bo,d.normalizeUnits=m,d.relativeTimeRounding=ri,d.relativeTimeThreshold=oi,d.calendarFormat=Ba,d.prototype=P,d.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},d}()}.call(this,fi(535)(e))},function(e,t,n){"use strict";t.__esModule=!0;var a=u(n(3)),r=u(n(16)),o=u(n(6)),i=u(n(373)),s=u(n(601)),l=u(n(602)),n=u(n(375));function u(e){return e&&e.__esModule?e:{default:e}}i.default.Password=o.default.config(s.default,{exportNames:["getInputNode","focus"],transform:function(e,t){var n;return"hasLimitHint"in e&&(t("hasLimitHint","showLimitHint","Input"),n=(t=e).hasLimitHint,t=(0,r.default)(t,["hasLimitHint"]),e=(0,a.default)({showLimitHint:n},t)),e}}),i.default.TextArea=o.default.config(l.default,{exportNames:["getInputNode","focus"],transform:function(e,t){var n;return"hasLimitHint"in e&&(t("hasLimitHint","showLimitHint","Input"),n=(t=e).hasLimitHint,t=(0,r.default)(t,["hasLimitHint"]),e=(0,a.default)({showLimitHint:n},t)),e}}),i.default.Group=n.default,t.default=o.default.config(i.default,{exportNames:["getInputNode","focus"],transform:function(e,t){var n;return"hasLimitHint"in e&&(t("hasLimitHint","showLimitHint","Input"),n=(t=e).hasLimitHint,t=(0,r.default)(t,["hasLimitHint"]),e=(0,a.default)({showLimitHint:n},t)),e}}),e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0,t.pickAttrs=t.datejs=t.htmlId=t.KEYCODE=t.guid=t.focus=t.support=t.str=t.obj=t.log=t.func=t.events=t.env=t.dom=void 0;var a=y(n(215)),r=y(n(218)),o=y(n(518)),i=y(n(519)),s=y(n(217)),l=y(n(101)),u=y(n(216)),c=y(n(527)),d=y(n(528)),f=y(n(529)),p=g(n(530)),h=g(n(220)),m=g(n(164)),n=g(n(531));function g(e){return e&&e.__esModule?e:{default:e}}function y(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t.default=e,t}t.dom=a,t.env=r,t.events=o,t.func=i,t.log=s,t.obj=l,t.str=u,t.support=c,t.focus=d,t.guid=p.default,t.KEYCODE=h.default,t.htmlId=f,t.datejs=m.default,t.pickAttrs=n.default},function(e,t,n){"use strict";function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}n.d(t,"a",function(){return a})},function(e,t,n){"use strict";function a(e,t){for(var n=0;n")),"shouldUpdatePosition"in r&&(delete t.shouldUpdatePosition,c.log.warning("Warning: [ shouldUpdatePosition ] is deprecated at [ ]")),"minMargin"in r&&o("minMargin","top/bottom",""),"isFullScreen"in r&&(r.overFlowScroll=!r.isFullScreen,delete t.isFullScreen,o("isFullScreen","overFlowScroll","")),t):(["target","offset","beforeOpen","onOpen","afterOpen","beforePosition","onPosition","cache","safeNode","wrapperClassName","container"].forEach(function(e){var t,n,a;e in r&&(o(e,"overlayProps."+e,"Dialog"),t=(n=r).overlayProps,n=(0,s.default)(n,["overlayProps"]),a=(0,i.default)(((a={})[e]=r[e],a),t||{}),delete n[e],r=(0,i.default)({overlayProps:a},n))}),r)}n.displayName="Dialog",n.Inner=p.default,n.show=function(e){return!1!==u.default.getContextProps(e,"Dialog").warning&&(e=v(e,c.log.deprecated)),(0,h.show)(e)},n.alert=function(e){return!1!==u.default.getContextProps(e,"Dialog").warning&&(e=v(e,c.log.deprecated)),(0,h.alert)(e)},n.confirm=function(e){return!1!==u.default.getContextProps(e,"Dialog").warning&&(e=v(e,c.log.deprecated)),(0,h.confirm)(e)},n.success=function(e){return(0,h.success)(e)},n.error=function(e){return(0,h.error)(e)},n.notice=function(e){return(0,h.notice)(e)},n.warning=function(e){return(0,h.warning)(e)},n.help=function(e){return(0,h.help)(e)},n.withContext=h.withContext,t.default=u.default.config(n,{transform:v}),e.exports=t.default},function(e,t,n){var a; +/*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/ +!function(){"use strict";var i={}.hasOwnProperty;function s(){for(var e=[],t=0;t 16.8.0")},p.prototype.validate=function(e,t){this.validateCallback(e,t)},p.prototype.reset=function(e){var t=1","Select");t=l(e,t);return e.onInputUpdate&&(t.onSearch=e.onInputUpdate,t.showSearch=!0),t}}),t.default=a.default.config(r.default,{transform:l,exportNames:["focusInput","handleSearchClear"]}),e.exports=t.default},function(e,t,n){"use strict";function l(){var e=this.constructor.getDerivedStateFromProps(this.props,this.state);null!=e&&this.setState(e)}function u(t){this.setState(function(e){return null!=(e=this.constructor.getDerivedStateFromProps(t,e))?e:null}.bind(this))}function c(e,t){try{var n=this.props,a=this.state;this.props=e,this.state=t,this.__reactInternalSnapshotFlag=!0,this.__reactInternalSnapshot=this.getSnapshotBeforeUpdate(n,a)}finally{this.props=n,this.state=a}}function a(e){var t=e.prototype;if(!t||!t.isReactComponent)throw new Error("Can only polyfill class components");if("function"==typeof e.getDerivedStateFromProps||"function"==typeof t.getSnapshotBeforeUpdate){var n,a,r=null,o=null,i=null;if("function"==typeof t.componentWillMount?r="componentWillMount":"function"==typeof t.UNSAFE_componentWillMount&&(r="UNSAFE_componentWillMount"),"function"==typeof t.componentWillReceiveProps?o="componentWillReceiveProps":"function"==typeof t.UNSAFE_componentWillReceiveProps&&(o="UNSAFE_componentWillReceiveProps"),"function"==typeof t.componentWillUpdate?i="componentWillUpdate":"function"==typeof t.UNSAFE_componentWillUpdate&&(i="UNSAFE_componentWillUpdate"),null!==r||null!==o||null!==i)throw n=e.displayName||e.name,a="function"==typeof e.getDerivedStateFromProps?"getDerivedStateFromProps()":"getSnapshotBeforeUpdate()",Error("Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n"+n+" uses "+a+" but also contains the following legacy lifecycles:"+(null!==r?"\n "+r:"")+(null!==o?"\n "+o:"")+(null!==i?"\n "+i:"")+"\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://fb.me/react-async-component-lifecycle-hooks");if("function"==typeof e.getDerivedStateFromProps&&(t.componentWillMount=l,t.componentWillReceiveProps=u),"function"==typeof t.getSnapshotBeforeUpdate){if("function"!=typeof t.componentDidUpdate)throw new Error("Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate() on the prototype");t.componentWillUpdate=c;var s=t.componentDidUpdate;t.componentDidUpdate=function(e,t,n){n=this.__reactInternalSnapshotFlag?this.__reactInternalSnapshot:n;s.call(this,e,t,n)}}}return e}n.r(t),n.d(t,"polyfill",function(){return a}),c.__suppressDeprecationWarning=u.__suppressDeprecationWarning=l.__suppressDeprecationWarning=!0},function(M,e,t){"use strict";t.d(e,"a",function(){return a}),t.d(e,"b",function(){return U});var x=t(0),C=t.n(x),c=C.a.createContext(null);function l(){return n}var n=function(e){e()};var r={notify:function(){},get:function(){return[]}};function T(t,n){var o,i=r;function s(){e.onStateChange&&e.onStateChange()}function a(){var e,a,r;o||(o=n?n.addNestedSub(s):t.subscribe(s),e=l(),r=a=null,i={clear:function(){r=a=null},notify:function(){e(function(){for(var e=a;e;)e.callback(),e=e.next})},get:function(){for(var e=[],t=a;t;)e.push(t),t=t.next;return e},subscribe:function(e){var t=!0,n=r={callback:e,next:null,prev:r};return n.prev?n.prev.next=n:a=n,function(){t&&null!==a&&(t=!1,n.next?n.next.prev=n.prev:r=n.prev,n.prev?n.prev.next=n.next:a=n.next)}}})}var e={addNestedSub:function(e){return a(),i.subscribe(e)},notifyNestedSubs:function(){i.notify()},handleChangeWrapper:s,isSubscribed:function(){return Boolean(o)},trySubscribe:a,tryUnsubscribe:function(){o&&(o(),o=void 0,i.clear(),i=r)},getListeners:function(){return i}};return e}var o="undefined"!=typeof window&&void 0!==window.document&&void 0!==window.document.createElement?x.useLayoutEffect:x.useEffect;var a=function(e){var t=e.store,n=e.context,e=e.children,a=Object(x.useMemo)(function(){var e=T(t);return{store:t,subscription:e}},[t]),r=Object(x.useMemo)(function(){return t.getState()},[t]),n=(o(function(){var e=a.subscription;return e.onStateChange=e.notifyNestedSubs,e.trySubscribe(),r!==t.getState()&&e.notifyNestedSubs(),function(){e.tryUnsubscribe(),e.onStateChange=null}},[a,r]),n||c);return C.a.createElement(n.Provider,{value:a},e)},L=t(41),O=t(56),e=t(107),d=t.n(e),D=t(430),f=["getDisplayName","methodName","renderCountProp","shouldHandleStateChanges","storeKey","withRef","forwardRef","context"],N=["reactReduxForwardedRef"],P=[],j=[null,null];function Y(e,t){e=e[1];return[t.payload,e+1]}function I(e,t,n){o(function(){return e.apply(void 0,t)},n)}function A(e,t,n,a,r,o,i){e.current=a,t.current=r,n.current=!1,o.current&&(o.current=null,i())}function R(e,a,t,r,o,i,s,l,u,c){var d,f;if(e)return d=!1,f=null,t.onStateChange=e=function(){if(!d){var e,t,n=a.getState();try{e=r(n,o.current)}catch(e){f=t=e}t||(f=null),e===i.current?s.current||u():(i.current=e,l.current=e,s.current=!0,c({type:"STORE_UPDATED",payload:{error:t}}))}},t.trySubscribe(),e(),function(){if(d=!0,t.tryUnsubscribe(),t.onStateChange=null,f)throw f}}var H=function(){return[null,0]};function i(k,e){var e=e=void 0===e?{}:e,t=e.getDisplayName,r=void 0===t?function(e){return"ConnectAdvanced("+e+")"}:t,t=e.methodName,o=void 0===t?"connectAdvanced":t,t=e.renderCountProp,i=void 0===t?void 0:t,t=e.shouldHandleStateChanges,S=void 0===t||t,t=e.storeKey,s=void 0===t?"store":t,t=(e.withRef,e.forwardRef),l=void 0!==t&&t,t=e.context,t=void 0===t?c:t,u=Object(O.a)(e,f),E=t;return function(b){var e=b.displayName||b.name||"Component",t=r(e),w=Object(L.a)({},u,{getDisplayName:r,methodName:o,renderCountProp:i,shouldHandleStateChanges:S,storeKey:s,displayName:t,wrappedComponentName:e,WrappedComponent:b}),e=u.pure;var M=e?x.useMemo:function(e){return e()};function n(n){var e=Object(x.useMemo)(function(){var e=n.reactReduxForwardedRef,t=Object(O.a)(n,N);return[n.context,e,t]},[n]),t=e[0],a=e[1],r=e[2],o=Object(x.useMemo)(function(){return t&&t.Consumer&&Object(D.isContextConsumer)(C.a.createElement(t.Consumer,null))?t:E},[t,E]),i=Object(x.useContext)(o),s=Boolean(n.store)&&Boolean(n.store.getState)&&Boolean(n.store.dispatch),l=(Boolean(i)&&Boolean(i.store),(s?n:i).store),u=Object(x.useMemo)(function(){return k(l.dispatch,w)},[l]),e=Object(x.useMemo)(function(){var e,t;return S?(t=(e=T(l,s?null:i.subscription)).notifyNestedSubs.bind(e),[e,t]):j},[l,s,i]),c=e[0],e=e[1],d=Object(x.useMemo)(function(){return s?i:Object(L.a)({},i,{subscription:c})},[s,i,c]),f=Object(x.useReducer)(Y,P,H),p=f[0][0],f=f[1];if(p&&p.error)throw p.error;var h=Object(x.useRef)(),m=Object(x.useRef)(r),g=Object(x.useRef)(),y=Object(x.useRef)(!1),v=M(function(){return g.current&&r===m.current?g.current:u(l.getState(),r)},[l,p,r]),_=(I(A,[m,h,y,r,v,g,e]),I(R,[S,l,c,u,m,h,y,g,e,f],[l,c,u]),Object(x.useMemo)(function(){return C.a.createElement(b,Object(L.a)({},v,{ref:a}))},[a,b,v]));return Object(x.useMemo)(function(){return S?C.a.createElement(o.Provider,{value:d},_):_},[o,_,d])}var a=e?C.a.memo(n):n;return a.WrappedComponent=b,a.displayName=n.displayName=t,l?((e=C.a.forwardRef(function(e,t){return C.a.createElement(a,Object(L.a)({},e,{reactReduxForwardedRef:t}))})).displayName=t,e.WrappedComponent=b,d()(e,b)):d()(a,b)}}function s(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function m(e,t){if(!s(e,t)){if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),a=Object.keys(t);if(n.length!==a.length)return!1;for(var r=0;re?t.splice(e,t.length-e,n):t.push(n),i({action:"PUSH",location:n,index:e,entries:t}))})},replace:function(e,t){var n=D(e,t,s(),u.location);o.confirmTransitionTo(n,"REPLACE",a,function(e){e&&i({action:"REPLACE",location:u.entries[u.index]=n})})},go:l,goBack:function(){l(-1)},goForward:function(){l(1)},canGo:function(e){return 0<=(e=u.index+e)&&ex',"Tag"),"readonly"!==n&&"interactive"!==n||r.log.warning("Warning: [ shape="+n+" ] is deprecated at [ Tag ]"),"secondary"===a&&r.log.warning("Warning: [ type=secondary ] is deprecated at [ Tag ]"),["count","marked","value","onChange"].forEach(function(e){e in t&&r.log.warning("Warning: [ "+e+" ] is deprecated at [ Tag ]")}),("selected"in t||"defaultSelected"in t)&&r.log.warning("Warning: [ selected|defaultSelected ] is deprecated at [ Tag ], use [ checked|defaultChecked ] at [ Tag.Selectable ] instead of it"),"closed"in t&&r.log.warning("Warning: [ closed ] is deprecated at [ Tag ], use [ onClose ] at [ Tag.Closeable ] instead of it"),"onSelect"in t&&e("onSelect","","Tag"),"afterClose"in t&&r.log.warning("Warning: [ afterClose ] is deprecated at [ Tag ], use [ afterClose ] at [ Tag.Closeable ] instead of it"),t}});o.Group=a.default.config(i.default),o.Selectable=a.default.config(s.default),o.Closable=a.default.config(n.default),o.Closeable=o.Closable,t.default=o,e.exports=t.default},function(e,t,n){"use strict";n(72),n(466)},function(e,t){e=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=e)},function(e,t){e=e.exports={version:"2.6.12"};"number"==typeof __e&&(__e=e)},function(e,t,n){e.exports=!n(113)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t,n){"use strict";t.__esModule=!0;var a=o(n(358)),r=o(n(545)),n=o(n(546));function o(e){return e&&e.__esModule?e:{default:e}}a.default.Expand=r.default,a.default.OverlayAnimate=n.default,t.default=a.default,e.exports=t.default},function(e,t,n){"use strict";n(43),n(72),n(114),n(115),n(559)},function(e,t,n){"use strict";t.__esModule=!0;var r=p(n(3)),o=p(n(16)),a=p(n(6)),i=p(n(648)),s=p(n(649)),l=p(n(395)),u=p(n(397)),c=p(n(650)),d=p(n(651)),f=p(n(396)),n=p(n(398));function p(e){return e&&e.__esModule?e:{default:e}}i.default.Header=s.default,i.default.Media=u.default,i.default.Divider=c.default,i.default.Content=d.default,i.default.Actions=n.default,i.default.BulletHeader=l.default,i.default.CollaspeContent=f.default,i.default.CollapseContent=f.default,t.default=a.default.config(i.default,{transform:function(e,t){var n,a;return"titlePrefixLine"in e&&(t("titlePrefixLine","showTitleBullet","Card"),a=(n=e).titlePrefixLine,n=(0,o.default)(n,["titlePrefixLine"]),e=(0,r.default)({showTitleBullet:a},n)),"titleBottomLine"in e&&(t("titleBottomLine","showHeadDivider","Card"),n=(a=e).titleBottomLine,a=(0,o.default)(a,["titleBottomLine"]),e=(0,r.default)({showHeadDivider:n},a)),"bodyHeight"in e&&(t("bodyHeight","contentHeight","Card"),a=(n=e).bodyHeight,t=(0,o.default)(n,["bodyHeight"]),e=(0,r.default)({contentHeight:a},t)),e}}),e.exports=t.default},function(e,t,n){"use strict";n.d(t,"b",function(){return s});var a=n(19),r=n(33),o=n(22),i={namespaces:[]},s=function(e){return function(n){return r.a.get("v1/console/namespaces",{params:e}).then(function(e){var t=e.code,e=e.data;n({type:o.b,data:200===t?e:[]})})}};t.a=function(){var e=0this.menuNode.clientHeight&&(this.menuNode.clientHeight+this.menuNode.scrollTop<(e=this.itemNode.offsetTop+this.itemNode.offsetHeight)?this.menuNode.scrollTop=e-this.menuNode.clientHeight:this.itemNode.offsetTope.length)&&(t=e.length);for(var n=0,a=new Array(t);n>16&255),o.push(r>>8&255),o.push(255&r)),r=r<<6|a.indexOf(t.charAt(i));return 0==(e=n%4*6)?(o.push(r>>16&255),o.push(r>>8&255),o.push(255&r)):18==e?(o.push(r>>10&255),o.push(r>>2&255)):12==e&&o.push(r>>4&255),new Uint8Array(o)},predicate:function(e){return"[object Uint8Array]"===Object.prototype.toString.call(e)},represent:function(e){for(var t,n="",a=0,r=e.length,o=g,i=0;i>18&63]+o[a>>12&63])+o[a>>6&63]+o[63&a]),a=(a<<8)+e[i];return 0==(t=r%3)?n=(n=n+o[a>>18&63]+o[a>>12&63])+o[a>>6&63]+o[63&a]:2==t?n=(n=n+o[a>>10&63]+o[a>>4&63])+o[a<<2&63]+o[64]:1==t&&(n=(n=n+o[a>>2&63]+o[a<<4&63])+o[64]+o[64]),n}}),V=Object.prototype.hasOwnProperty,K=Object.prototype.toString;var s=new a("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(e){if(null!==e)for(var t,n,a,r=[],o=e,i=0,s=o.length;i>10),56320+(l-65536&1023)),e.position++}else x(e,"unknown escape sequence");n=a=e.position}else w(u)?(T(e,n,a,!0),P(e,D(e,!1,t)),n=a=e.position):e.position===e.lineStart&&N(e)?x(e,"unexpected end of the document within a double quoted scalar"):(e.position++,a=e.position)}x(e,"unexpected end of the stream within a double quoted scalar")}}function ge(e,t){var n,a,r=e.tag,o=e.anchor,i=[],s=!1;if(-1!==e.firstTabInLine)return!1;for(null!==e.anchor&&(e.anchorMap[e.anchor]=i),a=e.input.charCodeAt(e.position);0!==a&&(-1!==e.firstTabInLine&&(e.position=e.firstTabInLine,x(e,"tab characters must not be used in indentation")),45===a)&&k(e.input.charCodeAt(e.position+1));)if(s=!0,e.position++,D(e,!0,-1)&&e.lineIndent<=t)i.push(null),a=e.input.charCodeAt(e.position);else if(n=e.line,j(e,t,Z,!1,!0),i.push(e.result),D(e,!0,-1),a=e.input.charCodeAt(e.position),(e.line===n||e.lineIndent>t)&&0!==a)x(e,"bad indentation of a sequence entry");else if(e.lineIndentt?f=1:e.lineIndent===t?f=0:e.lineIndentt?f=1:e.lineIndent===t?f=0:e.lineIndentt)&&(y&&(i=e.line,s=e.lineStart,l=e.position),j(e,t,_,!0,r)&&(y?m=e.result:g=e.result),y||(L(e,f,p,h,m,g,i,s,l),h=m=g=null),D(e,!0,-1),u=e.input.charCodeAt(e.position)),(e.line===o||e.lineIndent>t)&&0!==u)x(e,"bad indentation of a mapping entry");else if(e.lineIndentl&&(l=e.lineIndent),w(d))u++;else{if(e.lineIndent=t){i=!0,f=e.input.charCodeAt(e.position);continue}e.position=o,e.line=s,e.lineStart=l,e.lineIndent=u;break}}i&&(T(e,r,o,!1),P(e,e.line-s),r=o=e.position,i=!1),M(f)||(o=e.position+1),f=e.input.charCodeAt(++e.position)}if(T(e,r,o,!1),e.result)return 1;e.kind=c,e.result=d}}(e,a,v===n)&&(h=!0,null===e.tag)&&(e.tag="?"):(h=!0,null===e.tag&&null===e.anchor||x(e,"alias node should not have any properties")),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):0===f&&(h=s&&ge(e,r))),null===e.tag)null!==e.anchor&&(e.anchorMap[e.anchor]=e.result);else if("?"===e.tag){for(null!==e.result&&"scalar"!==e.kind&&x(e,'unacceptable node kind for ! tag; it should be "scalar", not "'+e.kind+'"'),l=0,u=e.implicitTypes.length;l"),null!==e.result&&d.kind!==e.kind&&x(e,"unacceptable node kind for !<"+e.tag+'> tag; it should be "'+d.kind+'", not "'+e.kind+'"'),d.resolve(e.result,e.tag)?(e.result=d.construct(e.result,e.tag),null!==e.anchor&&(e.anchorMap[e.anchor]=e.result)):x(e,"cannot resolve a node with !<"+e.tag+"> explicit tag")}return null!==e.listener&&e.listener("close",e),null!==e.tag||null!==e.anchor||h}function ye(e,t){t=t||{};var n=new de(e=0!==(e=String(e)).length&&(10!==e.charCodeAt(e.length-1)&&13!==e.charCodeAt(e.length-1)&&(e+="\n"),65279===e.charCodeAt(0))?e.slice(1):e,t),t=e.indexOf("\0");for(-1!==t&&(n.position=t,x(n,"null byte is not allowed in input")),n.input+="\0";32===n.input.charCodeAt(n.position);)n.lineIndent+=1,n.position+=1;for(;n.positiondocument.F=Object<\/script>"),e.close(),u=e.F;t--;)delete u[l][i[t]];return u()};e.exports=Object.create||function(e,t){var n;return null!==e?(a[l]=r(e),n=new a,a[l]=null,n[s]=e):n=u(),void 0===t?n:o(n,t)}},function(e,t,n){var a=n(89).f,r=n(90),o=n(100)("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,o)&&a(e,o,{configurable:!0,value:t})}},function(e,t,n){t.f=n(100)},function(e,t,n){var a=n(80),r=n(81),o=n(128),i=n(162),s=n(89).f;e.exports=function(e){var t=r.Symbol||(r.Symbol=!o&&a.Symbol||{});"_"==e.charAt(0)||e in t||s(t,e,{value:i.f(e)})}},function(e,t,n){"use strict";t.__esModule=!0;var a=c(n(219)),r=c(n(520)),o=c(n(521)),i=c(n(522)),s=c(n(523)),l=c(n(524)),u=c(n(525));function c(e){return e&&e.__esModule?e:{default:e}}n(526),a.default.extend(l.default),a.default.extend(s.default),a.default.extend(r.default),a.default.extend(o.default),a.default.extend(i.default),a.default.extend(u.default),a.default.locale("zh-cn");n=a.default;n.isSelf=a.default.isDayjs,a.default.localeData(),t.default=n,e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0;var v=d(n(3)),o=d(n(4)),i=d(n(7)),a=d(n(8)),r=n(0),_=d(r),s=d(n(5)),l=n(30),b=d(n(18)),u=d(n(44)),w=d(n(26)),M=d(n(83)),c=d(n(6)),k=n(11);function d(e){return e&&e.__esModule?e:{default:e}}function f(){}p=r.Component,(0,a.default)(S,p),S.getDerivedStateFromProps=function(e){return"visible"in e?{visible:e.visible}:{}},S.prototype.render=function(){var e,t=this.props,n=t.prefix,a=(t.pure,t.className),r=t.style,o=t.type,i=t.shape,s=t.size,l=t.title,u=t.children,c=(t.defaultVisible,t.visible,t.iconType),d=t.closeable,f=(t.onClose,t.afterClose),p=t.animation,h=t.rtl,t=t.locale,m=(0,v.default)({},k.obj.pickOthers(Object.keys(S.propTypes),this.props)),g=this.state.visible,y=n+"message",o=(0,b.default)(((e={})[y]=!0,e[n+"message-"+o]=o,e[""+n+i]=i,e[""+n+s]=s,e[n+"title-content"]=!!l,e[n+"only-content"]=!l&&!!u,e[a]=a,e)),i=g?_.default.createElement("div",(0,v.default)({role:"alert",style:r},m,{className:o,dir:h?"rtl":void 0}),d?_.default.createElement("a",{role:"button","aria-label":t.closeAriaLabel,className:y+"-close",onClick:this.onClose},_.default.createElement(w.default,{type:"close"})):null,!1!==c?_.default.createElement(w.default,{className:y+"-symbol "+(!c&&y+"-symbol-icon"),type:c}):null,l?_.default.createElement("div",{className:y+"-title"},l):null,u?_.default.createElement("div",{className:y+"-content"},u):null):null;return p?_.default.createElement(M.default.Expand,{animationAppear:!1,afterLeave:f},i):i},r=n=S,n.propTypes={prefix:s.default.string,pure:s.default.bool,className:s.default.string,style:s.default.object,type:s.default.oneOf(["success","warning","error","notice","help","loading"]),shape:s.default.oneOf(["inline","addon","toast"]),size:s.default.oneOf(["medium","large"]),title:s.default.node,children:s.default.node,defaultVisible:s.default.bool,visible:s.default.bool,iconType:s.default.oneOfType([s.default.string,s.default.bool]),closeable:s.default.bool,onClose:s.default.func,afterClose:s.default.func,animation:s.default.bool,locale:s.default.object,rtl:s.default.bool},n.defaultProps={prefix:"next-",pure:!1,type:"success",shape:"inline",size:"medium",defaultVisible:!0,closeable:!1,onClose:f,afterClose:f,animation:!0,locale:u.default.Message};var p,a=r;function S(){var e,t;(0,o.default)(this,S);for(var n=arguments.length,a=Array(n),r=0;r=n.length?(l=!!(d=h(o,u)))&&"get"in d&&!("originalValue"in d.get)?d.get:o[u]:(l=_(o,u),o[u]),l&&!i&&(g[c]=o)}}return o}},function(e,t,n){"use strict";n=n(625);e.exports=Function.prototype.bind||n},function(e,t,n){"use strict";var a=String.prototype.replace,r=/%20/g,o="RFC1738",i="RFC3986";e.exports={default:i,formatters:{RFC1738:function(e){return a.call(e,r,"+")},RFC3986:function(e){return String(e)}},RFC1738:o,RFC3986:i}},function(e,t,n){"use strict";t.__esModule=!0,t.default=void 0;var c=l(n(3)),a=l(n(4)),r=l(n(7)),o=l(n(8)),d=n(0),f=l(d),i=l(n(5)),p=l(n(18)),h=l(n(26)),s=n(11),m=l(n(104));function l(e){return e&&e.__esModule?e:{default:e}}var u,g=s.func.bindCtx,y=s.obj.pickOthers,i=(u=d.Component,(0,o.default)(v,u),v.prototype.getSelected=function(){var e=this.props,t=e._key,n=e.root,e=e.selected,a=n.props.selectMode,n=n.state.selectedKeys;return e||!!a&&-1e.length&&e.every(function(e,t){return e===n[t]})},t.isAvailablePos=function(e,t,n){var n=n[t],a=n.type,n=n.disabled;return r(e,t)&&("item"===a&&!n||"submenu"===a)});t.getFirstAvaliablelChildKey=function(t,n){var e=Object.keys(n).find(function(e){return a(t+"-0",e,n)});return e?n[e].key:null},t.getChildSelected=function(e){var t,n=e.selectMode,a=e.selectedKeys,r=e._k2n,e=e._key;return!!r&&(t=(r[e]&&r[e].pos)+"-",!!n)&&a.some(function(e){return r[e]&&0===r[e].pos.indexOf(t)})}},function(e,t,n){"use strict";n(43),n(72),n(654)},function(e,t,n){"use strict";t.__esModule=!0;var g=d(n(16)),y=d(n(3)),a=d(n(4)),r=d(n(7)),o=d(n(8)),i=n(0),v=d(i),s=d(n(5)),_=d(n(18)),l=d(n(83)),u=d(n(26)),b=n(11),c=d(n(44)),n=d(n(6));function d(e){return e&&e.__esModule?e:{default:e}}var f,p=b.func.noop,h=b.func.bindCtx,m=/blue|green|orange|red|turquoise|yellow/,s=(f=i.Component,(0,o.default)(w,f),w.prototype.componentWillUnmount=function(){this.__destroyed=!0},w.prototype.handleClose=function(e){var t=this,n=this.props,a=n.animation,n=n.onClose,r=b.support.animation&&a;!1===n(e,this.tagNode)||this.__destroyed||this.setState({visible:!1},function(){r||t.props.afterClose(t.tagNode)})},w.prototype.handleBodyClick=function(e){var t=this.props,n=t.closable,a=t.closeArea,t=t.onClick,r=e.currentTarget;if(r&&(r===e.target||r.contains(e.target))&&(n&&"tag"===a&&this.handleClose("tag"),"function"==typeof t))return t(e)},w.prototype.handleTailClick=function(e){e&&e.preventDefault(),e&&e.stopPropagation(),this.handleClose("tail")},w.prototype.handleAnimationInit=function(e){this.props.afterAppear(e)},w.prototype.handleAnimationEnd=function(e){this.props.afterClose(e)},w.prototype.renderAnimatedTag=function(e,t){return v.default.createElement(l.default,{animation:t,afterAppear:this.handleAnimationInit,afterLeave:this.handleAnimationEnd},e)},w.prototype.renderTailNode=function(){var e=this.props,t=e.prefix,n=e.closable,e=e.locale;return n?v.default.createElement("span",{className:t+"tag-close-btn",onClick:this.handleTailClick,role:"button","aria-label":e.delete},v.default.createElement(u.default,{type:"close"})):null},w.prototype.isPresetColor=function(){var e=this.props.color;return!!e&&m.test(e)},w.prototype.getTagStyle=function(){var e=this.props,t=e.color,t=void 0===t?"":t,e=e.style,n=this.isPresetColor();return(0,y.default)({},t&&!n?{backgroundColor:t,borderColor:t,color:"#fff"}:null,e)},w.prototype.render=function(){var t=this,e=this.props,n=e.prefix,a=e.type,r=e.size,o=e.color,i=e._shape,s=e.closable,l=e.closeArea,u=e.className,c=e.children,d=e.animation,f=e.disabled,e=e.rtl,p=this.state.visible,h=this.isPresetColor(),m=b.obj.pickOthers(w.propTypes,this.props),m=(m.style,(0,g.default)(m,["style"])),r=(0,_.default)([n+"tag",n+"tag-"+(s?"closable":i),n+"tag-"+r],((i={})[n+"tag-level-"+a]=!o,i[n+"tag-closable"]=s,i[n+"tag-body-pointer"]=s&&"tag"===l,i[n+"tag-"+o]=o&&h&&"primary"===a,i[n+"tag-"+o+"-inverse"]=o&&h&&"normal"===a,i),u),s=this.renderTailNode(),l=p?v.default.createElement("div",(0,y.default)({className:r,onClick:this.handleBodyClick,onKeyDown:this.onKeyDown,tabIndex:f?"":"0",role:"button","aria-disabled":f,disabled:f,dir:e?"rtl":void 0,ref:function(e){return t.tagNode=e},style:this.getTagStyle()},m),v.default.createElement("span",{className:n+"tag-body"},c),s):null;return d&&b.support.animation?this.renderAnimatedTag(l,n+"tag-zoom"):l},o=i=w,i.propTypes={prefix:s.default.string,type:s.default.oneOf(["normal","primary"]),size:s.default.oneOf(["small","medium","large"]),color:s.default.string,animation:s.default.bool,closeArea:s.default.oneOf(["tag","tail"]),closable:s.default.bool,onClose:s.default.func,afterClose:s.default.func,afterAppear:s.default.func,className:s.default.any,children:s.default.node,onClick:s.default.func,_shape:s.default.oneOf(["default","closable","checkable"]),disabled:s.default.bool,rtl:s.default.bool,locale:s.default.object},i.defaultProps={prefix:"next-",type:"normal",size:"medium",closeArea:"tail",animation:!1,onClose:p,afterClose:p,afterAppear:p,onClick:p,_shape:"default",disabled:!1,rtl:!1,locale:c.default.Tag},o);function w(e){(0,a.default)(this,w);var o=(0,r.default)(this,f.call(this,e));return o.onKeyDown=function(e){var t=o.props,n=t.closable,a=t.closeArea,r=t.onClick,t=t.disabled;e.keyCode!==b.KEYCODE.SPACE||t||(e.preventDefault(),e.stopPropagation(),n?o.handleClose(a):"function"==typeof r&&r(e))},o.state={visible:!0},h(o,["handleBodyClick","handleTailClick","handleAnimationInit","handleAnimationEnd","renderTailNode"]),o}s.displayName="Tag",t.default=n.default.config(s),e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0;var f=r(n(16)),p=r(n(42)),h=r(n(3)),a=(t.isSingle=function(e){return!e||"single"===e},t.isNull=s,t.escapeForReg=o,t.filter=function(e,t){e=o(""+e),e=new RegExp("("+e+")","ig");return e.test(""+t.value)||e.test(""+t.label)},t.loopMap=i,t.parseDataSourceFromChildren=function i(e){var s=1{var t=new TomlError(e.message);return t.code=e.code,t.wrapped=e,t},module.exports.TomlError=TomlError;const createDateTime=__webpack_require__(697),createDateTimeFloat=__webpack_require__(698),createDate=__webpack_require__(699),createTime=__webpack_require__(700),CTRL_I=9,CTRL_J=10,CTRL_M=13,CTRL_CHAR_BOUNDARY=31,CHAR_SP=32,CHAR_QUOT=34,CHAR_NUM=35,CHAR_APOS=39,CHAR_PLUS=43,CHAR_COMMA=44,CHAR_HYPHEN=45,CHAR_PERIOD=46,CHAR_0=48,CHAR_1=49,CHAR_7=55,CHAR_9=57,CHAR_COLON=58,CHAR_EQUALS=61,CHAR_A=65,CHAR_E=69,CHAR_F=70,CHAR_T=84,CHAR_U=85,CHAR_Z=90,CHAR_LOWBAR=95,CHAR_a=97,CHAR_b=98,CHAR_e=101,CHAR_f=102,CHAR_i=105,CHAR_l=108,CHAR_n=110,CHAR_o=111,CHAR_r=114,CHAR_s=115,CHAR_t=116,CHAR_u=117,CHAR_x=120,CHAR_z=122,CHAR_LCUB=123,CHAR_RCUB=125,CHAR_LSQB=91,CHAR_BSOL=92,CHAR_RSQB=93,CHAR_DEL=127,SURROGATE_FIRST=55296,SURROGATE_LAST=57343,escapes={[CHAR_b]:"\b",[CHAR_t]:"\t",[CHAR_n]:"\n",[CHAR_f]:"\f",[CHAR_r]:"\r",[CHAR_QUOT]:'"',[CHAR_BSOL]:"\\"};function isDigit(e){return e>=CHAR_0&&e<=CHAR_9}function isHexit(e){return e>=CHAR_A&&e<=CHAR_F||e>=CHAR_a&&e<=CHAR_f||e>=CHAR_0&&e<=CHAR_9}function isBit(e){return e===CHAR_1||e===CHAR_0}function isOctit(e){return e>=CHAR_0&&e<=CHAR_7}function isAlphaNumQuoteHyphen(e){return e>=CHAR_A&&e<=CHAR_Z||e>=CHAR_a&&e<=CHAR_z||e>=CHAR_0&&e<=CHAR_9||e===CHAR_APOS||e===CHAR_QUOT||e===CHAR_LOWBAR||e===CHAR_HYPHEN}function isAlphaNumHyphen(e){return e>=CHAR_A&&e<=CHAR_Z||e>=CHAR_a&&e<=CHAR_z||e>=CHAR_0&&e<=CHAR_9||e===CHAR_LOWBAR||e===CHAR_HYPHEN}const _type=Symbol("type"),_declared=Symbol("declared"),hasOwnProperty=Object.prototype.hasOwnProperty,defineProperty=Object.defineProperty,descriptor={configurable:!0,enumerable:!0,writable:!0,value:void 0};function hasKey(e,t){if(hasOwnProperty.call(e,t))return 1;"__proto__"===t&&defineProperty(e,"__proto__",descriptor)}const INLINE_TABLE=Symbol("inline-table");function InlineTable(){return Object.defineProperties({},{[_type]:{value:INLINE_TABLE}})}function isInlineTable(e){return null!==e&&"object"==typeof e&&e[_type]===INLINE_TABLE}const TABLE=Symbol("table");function Table(){return Object.defineProperties({},{[_type]:{value:TABLE},[_declared]:{value:!1,writable:!0}})}function isTable(e){return null!==e&&"object"==typeof e&&e[_type]===TABLE}const _contentType=Symbol("content-type"),INLINE_LIST=Symbol("inline-list");function InlineList(e){return Object.defineProperties([],{[_type]:{value:INLINE_LIST},[_contentType]:{value:e}})}function isInlineList(e){return null!==e&&"object"==typeof e&&e[_type]===INLINE_LIST}const LIST=Symbol("list");function List(){return Object.defineProperties([],{[_type]:{value:LIST}})}function isList(e){return null!==e&&"object"==typeof e&&e[_type]===LIST}let _custom;try{const utilInspect=eval("require('util').inspect");_custom=utilInspect.custom}catch(_){}const _inspect=_custom||"inspect";class BoxedBigInt{constructor(e){try{this.value=global.BigInt.asIntN(64,e)}catch(e){this.value=null}Object.defineProperty(this,_type,{value:INTEGER})}isNaN(){return null===this.value}toString(){return String(this.value)}[_inspect](){return`[BigInt: ${this.toString()}]}`}valueOf(){return this.value}}const INTEGER=Symbol("integer");function Integer(e){let t=Number(e);return Object.is(t,-0)&&(t=0),global.BigInt&&!Number.isSafeInteger(t)?new BoxedBigInt(e):Object.defineProperties(new Number(t),{isNaN:{value:function(){return isNaN(this)}},[_type]:{value:INTEGER},[_inspect]:{value:()=>`[Integer: ${e}]`}})}function isInteger(e){return null!==e&&"object"==typeof e&&e[_type]===INTEGER}const FLOAT=Symbol("float");function Float(e){return Object.defineProperties(new Number(e),{[_type]:{value:FLOAT},[_inspect]:{value:()=>`[Float: ${e}]`}})}function isFloat(e){return null!==e&&"object"==typeof e&&e[_type]===FLOAT}function tomlType(e){var t=typeof e;if("object"==t){if(null===e)return"null";if(e instanceof Date)return"datetime";if(_type in e)switch(e[_type]){case INLINE_TABLE:return"inline-table";case INLINE_LIST:return"inline-list";case TABLE:return"table";case LIST:return"list";case FLOAT:return"float";case INTEGER:return"integer"}}return t}function makeParserClass(e){class t extends e{constructor(){super(),this.ctx=this.obj=Table()}atEndOfWord(){return this.char===CHAR_NUM||this.char===CTRL_I||this.char===CHAR_SP||this.atEndOfLine()}atEndOfLine(){return this.char===e.END||this.char===CTRL_J||this.char===CTRL_M}parseStart(){if(this.char===e.END)return null;if(this.char===CHAR_LSQB)return this.call(this.parseTableOrList);if(this.char===CHAR_NUM)return this.call(this.parseComment);if(this.char===CTRL_J||this.char===CHAR_SP||this.char===CTRL_I||this.char===CTRL_M)return null;if(isAlphaNumQuoteHyphen(this.char))return this.callNow(this.parseAssignStatement);throw this.error(new TomlError(`Unknown character "${this.char}"`))}parseWhitespaceToEOL(){if(this.char===CHAR_SP||this.char===CTRL_I||this.char===CTRL_M)return null;if(this.char===CHAR_NUM)return this.goto(this.parseComment);if(this.char===e.END||this.char===CTRL_J)return this.return();throw this.error(new TomlError("Unexpected character, expected only whitespace or comments till end of line"))}parseAssignStatement(){return this.callNow(this.parseAssign,this.recordAssignStatement)}recordAssignStatement(e){let t=this.ctx;var n,a=e.key.pop();for(n of e.key){if(hasKey(t,n)&&!isTable(t[n]))throw this.error(new TomlError("Can't redefine existing key"));t=t[n]=t[n]||Table()}if(hasKey(t,a))throw this.error(new TomlError("Can't redefine existing key"));return t[_declared]=!0,isInteger(e.value)||isFloat(e.value)?t[a]=e.value.valueOf():t[a]=e.value,this.goto(this.parseWhitespaceToEOL)}parseAssign(){return this.callNow(this.parseKeyword,this.recordAssignKeyword)}recordAssignKeyword(e){return this.state.resultTable?this.state.resultTable.push(e):this.state.resultTable=[e],this.goto(this.parseAssignKeywordPreDot)}parseAssignKeywordPreDot(){return this.char===CHAR_PERIOD?this.next(this.parseAssignKeywordPostDot):this.char!==CHAR_SP&&this.char!==CTRL_I?this.goto(this.parseAssignEqual):void 0}parseAssignKeywordPostDot(){if(this.char!==CHAR_SP&&this.char!==CTRL_I)return this.callNow(this.parseKeyword,this.recordAssignKeyword)}parseAssignEqual(){if(this.char===CHAR_EQUALS)return this.next(this.parseAssignPreValue);throw this.error(new TomlError('Invalid character, expected "="'))}parseAssignPreValue(){return this.char===CHAR_SP||this.char===CTRL_I?null:this.callNow(this.parseValue,this.recordAssignValue)}recordAssignValue(e){return this.returnNow({key:this.state.resultTable,value:e})}parseComment(){do{if(this.char===e.END||this.char===CTRL_J)return this.return();if(this.char===CHAR_DEL||this.char<=CTRL_CHAR_BOUNDARY&&this.char!==CTRL_I)throw this.errorControlCharIn("comments")}while(this.nextChar())}parseTableOrList(){if(this.char!==CHAR_LSQB)return this.goto(this.parseTable);this.next(this.parseList)}parseTable(){return this.ctx=this.obj,this.goto(this.parseTableNext)}parseTableNext(){return this.char===CHAR_SP||this.char===CTRL_I?null:this.callNow(this.parseKeyword,this.parseTableMore)}parseTableMore(e){if(this.char===CHAR_SP||this.char===CTRL_I)return null;if(this.char===CHAR_RSQB){if(!hasKey(this.ctx,e)||isTable(this.ctx[e])&&!this.ctx[e][_declared])return this.ctx=this.ctx[e]=this.ctx[e]||Table(),this.ctx[_declared]=!0,this.next(this.parseWhitespaceToEOL);throw this.error(new TomlError("Can't redefine existing key"))}if(this.char!==CHAR_PERIOD)throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));if(hasKey(this.ctx,e))if(isTable(this.ctx[e]))this.ctx=this.ctx[e];else{if(!isList(this.ctx[e]))throw this.error(new TomlError("Can't redefine existing key"));this.ctx=this.ctx[e][this.ctx[e].length-1]}else this.ctx=this.ctx[e]=Table();return this.next(this.parseTableNext)}parseList(){return this.ctx=this.obj,this.goto(this.parseListNext)}parseListNext(){return this.char===CHAR_SP||this.char===CTRL_I?null:this.callNow(this.parseKeyword,this.parseListMore)}parseListMore(e){if(this.char===CHAR_SP||this.char===CTRL_I)return null;if(this.char===CHAR_RSQB){if(hasKey(this.ctx,e)||(this.ctx[e]=List()),isInlineList(this.ctx[e]))throw this.error(new TomlError("Can't extend an inline array"));var t;if(isList(this.ctx[e]))return t=Table(),this.ctx[e].push(t),this.ctx=t,this.next(this.parseListEnd);throw this.error(new TomlError("Can't redefine an existing key"))}if(this.char!==CHAR_PERIOD)throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"));if(hasKey(this.ctx,e)){if(isInlineList(this.ctx[e]))throw this.error(new TomlError("Can't extend an inline array"));if(isInlineTable(this.ctx[e]))throw this.error(new TomlError("Can't extend an inline table"));if(isList(this.ctx[e]))this.ctx=this.ctx[e][this.ctx[e].length-1];else{if(!isTable(this.ctx[e]))throw this.error(new TomlError("Can't redefine an existing key"));this.ctx=this.ctx[e]}}else this.ctx=this.ctx[e]=Table();return this.next(this.parseListNext)}parseListEnd(e){if(this.char===CHAR_RSQB)return this.next(this.parseWhitespaceToEOL);throw this.error(new TomlError("Unexpected character, expected whitespace, . or ]"))}parseValue(){if(this.char===e.END)throw this.error(new TomlError("Key without value"));if(this.char===CHAR_QUOT)return this.next(this.parseDoubleString);if(this.char===CHAR_APOS)return this.next(this.parseSingleString);if(this.char===CHAR_HYPHEN||this.char===CHAR_PLUS)return this.goto(this.parseNumberSign);if(this.char===CHAR_i)return this.next(this.parseInf);if(this.char===CHAR_n)return this.next(this.parseNan);if(isDigit(this.char))return this.goto(this.parseNumberOrDateTime);if(this.char===CHAR_t||this.char===CHAR_f)return this.goto(this.parseBoolean);if(this.char===CHAR_LSQB)return this.call(this.parseInlineList,this.recordValue);if(this.char===CHAR_LCUB)return this.call(this.parseInlineTable,this.recordValue);throw this.error(new TomlError("Unexpected character, expecting string, number, datetime, boolean, inline array or inline table"))}recordValue(e){return this.returnNow(e)}parseInf(){if(this.char===CHAR_n)return this.next(this.parseInf2);throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'))}parseInf2(){if(this.char===CHAR_f)return"-"===this.state.buf?this.return(-1/0):this.return(1/0);throw this.error(new TomlError('Unexpected character, expected "inf", "+inf" or "-inf"'))}parseNan(){if(this.char===CHAR_a)return this.next(this.parseNan2);throw this.error(new TomlError('Unexpected character, expected "nan"'))}parseNan2(){if(this.char===CHAR_n)return this.return(NaN);throw this.error(new TomlError('Unexpected character, expected "nan"'))}parseKeyword(){return this.char===CHAR_QUOT?this.next(this.parseBasicString):this.char===CHAR_APOS?this.next(this.parseLiteralString):this.goto(this.parseBareKey)}parseBareKey(){do{if(this.char===e.END)throw this.error(new TomlError("Key ended without value"));if(!isAlphaNumHyphen(this.char)){if(0===this.state.buf.length)throw this.error(new TomlError("Empty bare keys are not allowed"));return this.returnNow()}}while(this.consume(),this.nextChar())}parseSingleString(){return this.char===CHAR_APOS?this.next(this.parseLiteralMultiStringMaybe):this.goto(this.parseLiteralString)}parseLiteralString(){do{if(this.char===CHAR_APOS)return this.return();if(this.atEndOfLine())throw this.error(new TomlError("Unterminated string"));if(this.char===CHAR_DEL||this.char<=CTRL_CHAR_BOUNDARY&&this.char!==CTRL_I)throw this.errorControlCharIn("strings")}while(this.consume(),this.nextChar())}parseLiteralMultiStringMaybe(){return this.char===CHAR_APOS?this.next(this.parseLiteralMultiString):this.returnNow()}parseLiteralMultiString(){return this.char===CTRL_M?null:this.char===CTRL_J?this.next(this.parseLiteralMultiStringContent):this.goto(this.parseLiteralMultiStringContent)}parseLiteralMultiStringContent(){do{if(this.char===CHAR_APOS)return this.next(this.parseLiteralMultiEnd);if(this.char===e.END)throw this.error(new TomlError("Unterminated multi-line string"));if(this.char===CHAR_DEL||this.char<=CTRL_CHAR_BOUNDARY&&this.char!==CTRL_I&&this.char!==CTRL_J&&this.char!==CTRL_M)throw this.errorControlCharIn("strings")}while(this.consume(),this.nextChar())}parseLiteralMultiEnd(){return this.char===CHAR_APOS?this.next(this.parseLiteralMultiEnd2):(this.state.buf+="'",this.goto(this.parseLiteralMultiStringContent))}parseLiteralMultiEnd2(){return this.char===CHAR_APOS?this.next(this.parseLiteralMultiEnd3):(this.state.buf+="''",this.goto(this.parseLiteralMultiStringContent))}parseLiteralMultiEnd3(){return this.char===CHAR_APOS?(this.state.buf+="'",this.next(this.parseLiteralMultiEnd4)):this.returnNow()}parseLiteralMultiEnd4(){return this.char===CHAR_APOS?(this.state.buf+="'",this.return()):this.returnNow()}parseDoubleString(){return this.char===CHAR_QUOT?this.next(this.parseMultiStringMaybe):this.goto(this.parseBasicString)}parseBasicString(){do{if(this.char===CHAR_BSOL)return this.call(this.parseEscape,this.recordEscapeReplacement);if(this.char===CHAR_QUOT)return this.return();if(this.atEndOfLine())throw this.error(new TomlError("Unterminated string"));if(this.char===CHAR_DEL||this.char<=CTRL_CHAR_BOUNDARY&&this.char!==CTRL_I)throw this.errorControlCharIn("strings")}while(this.consume(),this.nextChar())}recordEscapeReplacement(e){return this.state.buf+=e,this.goto(this.parseBasicString)}parseMultiStringMaybe(){return this.char===CHAR_QUOT?this.next(this.parseMultiString):this.returnNow()}parseMultiString(){return this.char===CTRL_M?null:this.char===CTRL_J?this.next(this.parseMultiStringContent):this.goto(this.parseMultiStringContent)}parseMultiStringContent(){do{if(this.char===CHAR_BSOL)return this.call(this.parseMultiEscape,this.recordMultiEscapeReplacement);if(this.char===CHAR_QUOT)return this.next(this.parseMultiEnd);if(this.char===e.END)throw this.error(new TomlError("Unterminated multi-line string"));if(this.char===CHAR_DEL||this.char<=CTRL_CHAR_BOUNDARY&&this.char!==CTRL_I&&this.char!==CTRL_J&&this.char!==CTRL_M)throw this.errorControlCharIn("strings")}while(this.consume(),this.nextChar())}errorControlCharIn(e){let t="\\u00";return this.char<16&&(t+="0"),t+=this.char.toString(16),this.error(new TomlError(`Control characters (codes < 0x1f and 0x7f) are not allowed in ${e}, use ${t} instead`))}recordMultiEscapeReplacement(e){return this.state.buf+=e,this.goto(this.parseMultiStringContent)}parseMultiEnd(){return this.char===CHAR_QUOT?this.next(this.parseMultiEnd2):(this.state.buf+='"',this.goto(this.parseMultiStringContent))}parseMultiEnd2(){return this.char===CHAR_QUOT?this.next(this.parseMultiEnd3):(this.state.buf+='""',this.goto(this.parseMultiStringContent))}parseMultiEnd3(){return this.char===CHAR_QUOT?(this.state.buf+='"',this.next(this.parseMultiEnd4)):this.returnNow()}parseMultiEnd4(){return this.char===CHAR_QUOT?(this.state.buf+='"',this.return()):this.returnNow()}parseMultiEscape(){return this.char===CTRL_M||this.char===CTRL_J?this.next(this.parseMultiTrim):this.char===CHAR_SP||this.char===CTRL_I?this.next(this.parsePreMultiTrim):this.goto(this.parseEscape)}parsePreMultiTrim(){if(this.char===CHAR_SP||this.char===CTRL_I)return null;if(this.char===CTRL_M||this.char===CTRL_J)return this.next(this.parseMultiTrim);throw this.error(new TomlError("Can't escape whitespace"))}parseMultiTrim(){return this.char===CTRL_J||this.char===CHAR_SP||this.char===CTRL_I||this.char===CTRL_M?null:this.returnNow()}parseEscape(){if(this.char in escapes)return this.return(escapes[this.char]);if(this.char===CHAR_u)return this.call(this.parseSmallUnicode,this.parseUnicodeReturn);if(this.char===CHAR_U)return this.call(this.parseLargeUnicode,this.parseUnicodeReturn);throw this.error(new TomlError("Unknown escape character: "+this.char))}parseUnicodeReturn(e){try{var t=parseInt(e,16);if(t>=SURROGATE_FIRST&&t<=SURROGATE_LAST)throw this.error(new TomlError("Invalid unicode, character in range 0xD800 - 0xDFFF is reserved"));return this.returnNow(String.fromCodePoint(t))}catch(e){throw this.error(TomlError.wrap(e))}}parseSmallUnicode(){if(!isHexit(this.char))throw this.error(new TomlError("Invalid character in unicode sequence, expected hex"));if(this.consume(),4<=this.state.buf.length)return this.return()}parseLargeUnicode(){if(!isHexit(this.char))throw this.error(new TomlError("Invalid character in unicode sequence, expected hex"));if(this.consume(),8<=this.state.buf.length)return this.return()}parseNumberSign(){return this.consume(),this.next(this.parseMaybeSignedInfOrNan)}parseMaybeSignedInfOrNan(){return this.char===CHAR_i?this.next(this.parseInf):this.char===CHAR_n?this.next(this.parseNan):this.callNow(this.parseNoUnder,this.parseNumberIntegerStart)}parseNumberIntegerStart(){return this.char===CHAR_0?(this.consume(),this.next(this.parseNumberIntegerExponentOrDecimal)):this.goto(this.parseNumberInteger)}parseNumberIntegerExponentOrDecimal(){return this.char===CHAR_PERIOD?(this.consume(),this.call(this.parseNoUnder,this.parseNumberFloat)):this.char===CHAR_E||this.char===CHAR_e?(this.consume(),this.next(this.parseNumberExponentSign)):this.returnNow(Integer(this.state.buf))}parseNumberInteger(){if(!isDigit(this.char)){if(this.char===CHAR_LOWBAR)return this.call(this.parseNoUnder);if(this.char===CHAR_E||this.char===CHAR_e)return this.consume(),this.next(this.parseNumberExponentSign);if(this.char===CHAR_PERIOD)return this.consume(),this.call(this.parseNoUnder,this.parseNumberFloat);var e=Integer(this.state.buf);if(e.isNaN())throw this.error(new TomlError("Invalid number"));return this.returnNow(e)}this.consume()}parseNoUnder(){if(this.char===CHAR_LOWBAR||this.char===CHAR_PERIOD||this.char===CHAR_E||this.char===CHAR_e)throw this.error(new TomlError("Unexpected character, expected digit"));if(this.atEndOfWord())throw this.error(new TomlError("Incomplete number"));return this.returnNow()}parseNoUnderHexOctBinLiteral(){if(this.char===CHAR_LOWBAR||this.char===CHAR_PERIOD)throw this.error(new TomlError("Unexpected character, expected digit"));if(this.atEndOfWord())throw this.error(new TomlError("Incomplete number"));return this.returnNow()}parseNumberFloat(){return this.char===CHAR_LOWBAR?this.call(this.parseNoUnder,this.parseNumberFloat):isDigit(this.char)?void this.consume():this.char===CHAR_E||this.char===CHAR_e?(this.consume(),this.next(this.parseNumberExponentSign)):this.returnNow(Float(this.state.buf))}parseNumberExponentSign(){if(isDigit(this.char))return this.goto(this.parseNumberExponent);if(this.char!==CHAR_HYPHEN&&this.char!==CHAR_PLUS)throw this.error(new TomlError("Unexpected character, expected -, + or digit"));this.consume(),this.call(this.parseNoUnder,this.parseNumberExponent)}parseNumberExponent(){if(!isDigit(this.char))return this.char===CHAR_LOWBAR?this.call(this.parseNoUnder):this.returnNow(Float(this.state.buf));this.consume()}parseNumberOrDateTime(){return this.char===CHAR_0?(this.consume(),this.next(this.parseNumberBaseOrDateTime)):this.goto(this.parseNumberOrDateTimeOnly)}parseNumberOrDateTimeOnly(){return this.char===CHAR_LOWBAR?this.call(this.parseNoUnder,this.parseNumberInteger):isDigit(this.char)?(this.consume(),void(4{for(t=String(t);t.length "+o[t]+"\n")+(n+" ");for(let e=0;er&&!o.warned&&(o.warned=!0,(a=new Error("Possible EventEmitter memory leak detected. "+o.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit")).name="MaxListenersExceededWarning",a.emitter=e,a.type=t,a.count=o.length,n=a,console)&&console.warn&&console.warn(n)),e}function f(e,t,n){e={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},t=function(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}.bind(e);return t.listener=n,e.wrapFn=t}function p(e,t,n){e=e._events;if(void 0===e)return[];e=e[t];if(void 0===e)return[];if("function"==typeof e)return n?[e.listener||e]:[e];if(n){for(var a=e,r=new Array(a.length),o=0;o=u,u=(0,D.default)(((u={})[n+"upload-inner"]=!0,u[n+"hidden"]=x,u)),C=this.props.children;return"card"===r&&(r=(0,D.default)(((r={})[n+"upload-card"]=!0,r[n+"disabled"]=l,r)),C=O.default.createElement("div",{className:r},O.default.createElement(P.default,{size:"large",type:"add",className:n+"upload-add-icon"}),O.default.createElement("div",{tabIndex:"0",role:"button",className:n+"upload-text"},C))),b?"function"==typeof w?(b=(0,D.default)(((r={})[n+"form-preview"]=!0,r[o]=!!o,r)),O.default.createElement("div",{style:i,className:b},w(this.state.value,this.props))):t?O.default.createElement(Y.default,{isPreview:!0,listType:t,style:i,className:o,value:this.state.value,onPreview:m}):null:(n=l?N.func.prevent:p,r=N.obj.pickAttrsWith(this.props,"data-"),O.default.createElement("div",(0,T.default)({className:f,style:i},r),O.default.createElement(j.default,(0,T.default)({},e,{name:M,beforeUpload:d,dragable:a,disabled:l||x,className:u,onSelect:this.onSelect,onDrop:this.onDrop,onProgress:this.onProgress,onSuccess:this.onSuccess,onError:this.onError,ref:this.saveUploaderRef}),C),t||g?O.default.createElement(Y.default,{useDataURL:s,fileNameRender:k,actionRender:S,uploader:this,listType:t,value:this.state.value,closable:c,onRemove:n,progressProps:v,onCancel:h,onPreview:m,extraRender:y,rtl:_,previewOnFileName:E}):null))},i=u=h,u.displayName="Upload",u.propTypes=(0,T.default)({},c.default.propTypes,Y.default.propTypes,{prefix:s.default.string.isRequired,action:s.default.string,value:s.default.array,defaultValue:s.default.array,shape:s.default.oneOf(["card"]),listType:s.default.oneOf(["text","image","card"]),list:s.default.any,name:s.default.string,data:s.default.oneOfType([s.default.object,s.default.func]),formatter:s.default.func,limit:s.default.number,timeout:s.default.number,dragable:s.default.bool,closable:s.default.bool,useDataURL:s.default.bool,disabled:s.default.bool,onSelect:s.default.func,onProgress:s.default.func,onChange:s.default.func,onSuccess:s.default.func,afterSelect:s.default.func,onRemove:s.default.func,onError:s.default.func,beforeUpload:s.default.func,onDrop:s.default.func,className:s.default.string,style:s.default.object,children:s.default.node,autoUpload:s.default.bool,request:s.default.func,progressProps:s.default.object,rtl:s.default.bool,isPreview:s.default.bool,renderPreview:s.default.func,fileKeyName:s.default.string,fileNameRender:s.default.func,actionRender:s.default.func,previewOnFileName:s.default.bool}),u.defaultProps=(0,T.default)({},c.default.defaultProps,{prefix:"next-",limit:1/0,autoUpload:!0,closable:!0,onSelect:n,onProgress:n,onChange:n,onSuccess:n,onRemove:n,onError:n,onDrop:n,beforeUpload:n,afterSelect:n,previewOnFileName:!1}),a=function(){var u=this;this.onSelect=function(e){var t,n,a=u.props,r=a.autoUpload,o=a.afterSelect,i=a.onSelect,a=a.limit,s=u.state.value.length+e.length,l=a-u.state.value.length;l<=0||(t=e=e.map(function(e){e=(0,d.fileToObject)(e);return e.state="selected",e}),n=[],ai||s+a.width>o):t<0||e<0||t+a.height>u.height||e+a.width>u.width}function L(e,t,n,a){var r=a.overlayInfo,a=a.containerInfo,n=n.split("");return 1===n.length&&n.push(""),t<0&&(n=[n[0].replace("t","b"),n[1].replace("b","t")]),e<0&&(n=[n[0].replace("l","r"),n[1].replace("r","l")]),t+r.height>a.height&&(n=[n[0].replace("b","t"),n[1].replace("t","b")]),(n=e+r.width>a.width?[n[0].replace("r","l"),n[1].replace("l","r")]:n).join("")}function O(e,t,n){var a=n.overlayInfo,n=n.containerInfo;return(t=t<0?0:t)+a.height>n.height&&(t=n.height-a.height),{left:e=(e=e<0?0:e)+a.width>n.width?n.width-a.width:e,top:t}}function be(e){var r,o,i,s,t,n,a,l,u,c,d,f=e.target,p=e.overlay,h=e.container,m=e.scrollNode,g=e.placement,y=e.placementOffset,y=void 0===y?0:y,v=e.points,v=void 0===v?["tl","bl"]:v,_=e.offset,_=void 0===_?[0,0]:_,b=e.position,b=void 0===b?"absolute":b,w=e.beforePosition,M=e.autoAdjust,M=void 0===M||M,k=e.autoHideScrollOverflow,k=void 0===k||k,e=e.rtl,S="offsetWidth"in(S=p)&&"offsetHeight"in S?{width:S.offsetWidth,height:S.offsetHeight}:{width:(S=S.getBoundingClientRect()).width,height:S.height},E=S.width,S=S.height;return"fixed"===b?(l={config:{placement:void 0,points:void 0},style:{position:b,left:_[0],top:_[1]}},w?w(l,{overlay:{node:p,width:E,height:S}}):l):(l=f.getBoundingClientRect(),r=l.width,o=l.height,i=l.left,s=l.top,t=(l=x(h)).left,l=l.top,u=h.scrollWidth,c=h.scrollHeight,n=h.scrollTop,a=h.scrollLeft,u=(l=C(g,t={targetInfo:{width:r,height:o,left:i,top:s},containerInfo:{left:t,top:l,width:u,height:c,scrollTop:n,scrollLeft:a},overlayInfo:{width:E,height:S},points:v,placementOffset:y,offset:_,container:h,rtl:e})).left,c=l.top,n=l.points,a=function(e){for(var t=e;t;){var n=he(t,"overflow");if(null!=n&&n.match(/auto|scroll|hidden/))return t;t=t.parentNode}return document.documentElement}(h),M&&g&&T(u,c,a,t)&&(g!==(v=L(u,c,g,t))&&(c=T(_=(y=C(v,t)).left,e=y.top,a,t)&&v!==(l=L(_,e,v,t))?(u=(M=O((h=C(g=l,t)).left,h.top,t)).left,M.top):(g=v,u=_,e)),u=(y=O(u,c,t)).left,c=y.top),d={config:{placement:g,points:n},style:{position:b,left:Math.round(u),top:Math.round(c)}},k&&g&&null!=m&&m.length&&m.forEach(function(e){var e=e.getBoundingClientRect(),t=e.top,n=e.left,a=e.width,e=e.height;d.style.display=s+o=e.length?{done:!0}:{done:!1,value:e[n++]}};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,a=new Array(t);nn.clientHeight&&0r;)!i(a,n=t[r++])||~l(o,n)||o.push(n);return o}},function(e,t,n){var a=n(209);e.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==a(e)?e.split(""):Object(e)}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t,n){"use strict";function y(){return this}var v=n(128),_=n(96),b=n(211),w=n(97),M=n(159),k=n(491),S=n(161),E=n(494),x=n(100)("iterator"),C=!([].keys&&"next"in[].keys()),T="values";e.exports=function(e,t,n,a,r,o,i){k(n,t,a);function s(e){if(!C&&e in f)return f[e];switch(e){case"keys":case T:return function(){return new n(this,e)}}return function(){return new n(this,e)}}var l,u,a=t+" Iterator",c=r==T,d=!1,f=e.prototype,p=f[x]||f["@@iterator"]||r&&f[r],h=p||s(r),m=r?c?s("entries"):h:void 0,g="Array"==t&&f.entries||p;if(g&&(g=E(g.call(new e)))!==Object.prototype&&g.next&&(S(g,a,!0),v||"function"==typeof g[x]||w(g,x,y)),c&&p&&p.name!==T&&(d=!0,h=function(){return p.call(this)}),v&&!i||!C&&!d&&f[x]||w(f,x,h),M[t]=h,M[a]=y,r)if(l={values:c?h:s(T),keys:o?h:s("keys"),entries:m},i)for(u in l)u in f||b(f,u,l[u]);else _(_.P+_.F*(C||d),t,l);return l}},function(e,t,n){e.exports=n(97)},function(e,t,n){var a=n(207),r=n(156).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return a(e,r)}},function(e,t,n){var a=n(130),r=n(126),o=n(99),i=n(151),s=n(90),l=n(205),u=Object.getOwnPropertyDescriptor;t.f=n(82)?u:function(e,t){if(e=o(e),t=i(t,!0),l)try{return u(e,t)}catch(e){}if(s(e,t))return r(!a.f.call(e,t),e[t])}},function(e,t,n){"use strict";t.__esModule=!0;var v=a(n(3));t.default=function(e,t,n){var a=e.prefix,r=e.locale,o=(e.defaultPropsConfig,e.pure),i=e.rtl,s=e.device,l=e.popupContainer,e=e.errorBoundary,u=t.nextPrefix,c=t.nextLocale,d=t.nextDefaultPropsConfig,f=t.nextPure,p=t.nextWarning,h=t.nextRtl,m=t.nextDevice,g=t.nextPopupContainer,t=t.nextErrorBoundary,a=a||u,u=void 0,y=n;switch(n){case"DatePicker2":y="DatePicker";break;case"Calendar2":y="Calendar";break;case"TimePicker2":y="TimePicker"}c&&(u=c[y])&&(u.momentLocale=c.momentLocale);n=void 0;r?n=b.obj.deepMerge({},_.default[y],u,r):u&&(n=b.obj.deepMerge({},_.default[y],u));c="boolean"==typeof o?o:f,r="boolean"==typeof i?i:h,u=(0,v.default)({},w(t),w(e));"open"in u||(u.open=!1);return{prefix:a,locale:n,pure:c,rtl:r,warning:p,defaultPropsConfig:d||{},device:s||m||void 0,popupContainer:l||g,errorBoundary:u}};var _=a(n(44)),b=n(11);function a(e){return e&&e.__esModule?e:{default:e}}var w=function(e){return null==e?{}:"boolean"==typeof e?{open:e}:(0,v.default)({open:!0},e)};e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0,t.matches=t.hasDOM=void 0;var a=n(42),r=(a=a)&&a.__esModule?a:{default:a},o=(t.hasClass=l,t.addClass=u,t.removeClass=c,t.toggleClass=function(e,t){if(!s||!e)return!1;{var n;return e.classList?e.classList.toggle(t):(((n=l(e,t))?c:u)(e,t,!0),!n)}},t.getNodeHozWhitespace=function(e){var t=m(e,"paddingLeft"),n=m(e,"paddingRight"),a=m(e,"marginLeft"),e=m(e,"marginRight");return t+n+a+e},t.getStyle=m,t.setStyle=g,t.scrollbar=v,t.hasScroll=function(e){if("hidden"===m(e,"overflow"))return!1;var t=e.parentNode;return t&&t.scrollHeight>t.clientHeight&&0=t?e:""+Array(t+1-a.length).join(n)+e},t={s:o,z:function(e){var t=-e.utcOffset(),n=Math.abs(t),a=Math.floor(n/60),r=n%60;return(t<=0?"+":"-")+o(a,2,"0")+":"+o(r,2,"0")},m:function e(t,n){if(t.date()1)return e(i[0])}else{var s=t.name;S[s]=t,r=s}return!a&&r&&(u=r),r||!a&&u},E=function(e,t){if(a(e))return e.clone();var n="object"==typeof t?t:{};return n.date=e,n.args=arguments,new s(n)},x=t,s=(x.l=r,x.i=a,x.w=function(e,t){return E(e,{locale:t.$L,utc:t.$u,x:t.$x,$offset:t.$offset})},function(){function e(e){this.$L=r(e.locale,null,!0),this.parse(e),this.$x=this.$x||e.x||{},this[n]=!0}var t=e.prototype;return t.parse=function(e){this.$d=function(e){var t=e.date,n=e.utc;if(null===t)return new Date(NaN);if(x.u(t))return new Date;if(t instanceof Date)return new Date(t);if("string"==typeof t&&!/Z$/i.test(t)){var a=t.match(i);if(a){var r=a[2]-1||0,o=(a[7]||"0").substring(0,3);return n?new Date(Date.UTC(a[1],r,a[3]||1,a[4]||0,a[5]||0,a[6]||0,o)):new Date(a[1],r,a[3]||1,a[4]||0,a[5]||0,a[6]||0,o)}}return new Date(t)}(e),this.init()},t.init=function(){var e=this.$d;this.$y=e.getFullYear(),this.$M=e.getMonth(),this.$D=e.getDate(),this.$W=e.getDay(),this.$H=e.getHours(),this.$m=e.getMinutes(),this.$s=e.getSeconds(),this.$ms=e.getMilliseconds()},t.$utils=function(){return x},t.isValid=function(){return!(this.$d.toString()===M)},t.isSame=function(e,t){var n=E(e);return this.startOf(t)<=n&&n<=this.endOf(t)},t.isAfter=function(e,t){return E(e)=20?"ste":"de")},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},n={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},s=function(e){return e===0?0:e===1?1:e===2?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},l={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},a=function(i){return function(e,t,n,a){var r=s(e),o=l[i][s(e)];if(r===2)o=o[t?0:1];return o.replace(/%d/i,e)}},r=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],o;e.defineLocale("ar",{months:r,monthsShort:r,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){if(e<12)return"ص";else return"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:a("s"),ss:a("s"),m:a("m"),mm:a("m"),h:a("h"),hh:a("h"),d:a("d"),dd:a("d"),M:a("M"),MM:a("M"),y:a("y"),yy:a("y")},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var s=function(e){return e===0?0:e===1?1:e===2?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},l={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},t=function(i){return function(e,t,n,a){var r=s(e),o=l[i][s(e)];if(r===2)o=o[t?0:1];return o.replace(/%d/i,e)}},n=["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويلية","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],a;e.defineLocale("ar-dz",{months:n,monthsShort:n,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){if(e<12)return"ص";else return"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:t("s"),ss:t("s"),m:t("m"),mm:t("m"),h:t("h"),hh:t("h"),d:t("d"),dd:t("d"),M:t("M"),MM:t("M"),y:t("y"),yy:t("y")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:0,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ar-kw",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:0,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"1",2:"2",3:"3",4:"4",5:"5",6:"6",7:"7",8:"8",9:"9",0:"0"},s=function(e){return e===0?0:e===1?1:e===2?2:e%100>=3&&e%100<=10?3:e%100>=11?4:5},l={s:["أقل من ثانية","ثانية واحدة",["ثانيتان","ثانيتين"],"%d ثوان","%d ثانية","%d ثانية"],m:["أقل من دقيقة","دقيقة واحدة",["دقيقتان","دقيقتين"],"%d دقائق","%d دقيقة","%d دقيقة"],h:["أقل من ساعة","ساعة واحدة",["ساعتان","ساعتين"],"%d ساعات","%d ساعة","%d ساعة"],d:["أقل من يوم","يوم واحد",["يومان","يومين"],"%d أيام","%d يومًا","%d يوم"],M:["أقل من شهر","شهر واحد",["شهران","شهرين"],"%d أشهر","%d شهرا","%d شهر"],y:["أقل من عام","عام واحد",["عامان","عامين"],"%d أعوام","%d عامًا","%d عام"]},n=function(i){return function(e,t,n,a){var r=s(e),o=l[i][s(e)];if(r===2)o=o[t?0:1];return o.replace(/%d/i,e)}},a=["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],r;e.defineLocale("ar-ly",{months:a,monthsShort:a,weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/‏M/‏YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){if(e<12)return"ص";else return"م"},calendar:{sameDay:"[اليوم عند الساعة] LT",nextDay:"[غدًا عند الساعة] LT",nextWeek:"dddd [عند الساعة] LT",lastDay:"[أمس عند الساعة] LT",lastWeek:"dddd [عند الساعة] LT",sameElse:"L"},relativeTime:{future:"بعد %s",past:"منذ %s",s:n("s"),ss:n("s"),m:n("m"),mm:n("m"),h:n("h"),hh:n("h"),d:n("d"),dd:n("d"),M:n("M"),MM:n("M"),y:n("y"),yy:n("y")},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ar-ma",{months:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"احد_اثنين_ثلاثاء_اربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},n={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},a;e.defineLocale("ar-sa",{months:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/ص|م/,isPM:function(e){return"م"===e},meridiem:function(e,t,n){if(e<12)return"ص";else return"م"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ar-tn",{months:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),monthsShort:"جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر".split("_"),weekdays:"الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت".split("_"),weekdaysShort:"أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت".split("_"),weekdaysMin:"ح_ن_ث_ر_خ_ج_س".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[اليوم على الساعة] LT",nextDay:"[غدا على الساعة] LT",nextWeek:"dddd [على الساعة] LT",lastDay:"[أمس على الساعة] LT",lastWeek:"dddd [على الساعة] LT",sameElse:"L"},relativeTime:{future:"في %s",past:"منذ %s",s:"ثوان",ss:"%d ثانية",m:"دقيقة",mm:"%d دقائق",h:"ساعة",hh:"%d ساعات",d:"يوم",dd:"%d أيام",M:"شهر",MM:"%d أشهر",y:"سنة",yy:"%d سنوات"},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var r={1:"-inci",5:"-inci",8:"-inci",70:"-inci",80:"-inci",2:"-nci",7:"-nci",20:"-nci",50:"-nci",3:"-üncü",4:"-üncü",100:"-üncü",6:"-ncı",9:"-uncu",10:"-uncu",30:"-uncu",60:"-ıncı",90:"-ıncı"},t;e.defineLocale("az",{months:"yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr".split("_"),monthsShort:"yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek".split("_"),weekdays:"Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə".split("_"),weekdaysShort:"Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən".split("_"),weekdaysMin:"Bz_BE_ÇA_Çə_CA_Cü_Şə".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[sabah saat] LT",nextWeek:"[gələn həftə] dddd [saat] LT",lastDay:"[dünən] LT",lastWeek:"[keçən həftə] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s əvvəl",s:"bir neçə saniyə",ss:"%d saniyə",m:"bir dəqiqə",mm:"%d dəqiqə",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",M:"bir ay",MM:"%d ay",y:"bir il",yy:"%d il"},meridiemParse:/gecə|səhər|gündüz|axşam/,isPM:function(e){return/^(gündüz|axşam)$/.test(e)},meridiem:function(e,t,n){if(e<4)return"gecə";else if(e<12)return"səhər";else if(e<17)return"gündüz";else return"axşam"},dayOfMonthOrdinalParse:/\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,ordinal:function(e){if(e===0)return e+"-ıncı";var t=e%10,n=e%100-t,a=e>=100?100:null;return e+(r[t]||r[n]||r[a])},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function r(e,t){var n=e.split("_");return t%10===1&&t%100!==11?n[0]:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?n[1]:n[2]}function t(e,t,n){var a={ss:t?"секунда_секунды_секунд":"секунду_секунды_секунд",mm:t?"хвіліна_хвіліны_хвілін":"хвіліну_хвіліны_хвілін",hh:t?"гадзіна_гадзіны_гадзін":"гадзіну_гадзіны_гадзін",dd:"дзень_дні_дзён",MM:"месяц_месяцы_месяцаў",yy:"год_гады_гадоў"};if(n==="m")return t?"хвіліна":"хвіліну";else if(n==="h")return t?"гадзіна":"гадзіну";else return e+" "+r(a[n],+e)}var n;e.defineLocale("be",{months:{format:"студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня".split("_"),standalone:"студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань".split("_")},monthsShort:"студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж".split("_"),weekdays:{format:"нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу".split("_"),standalone:"нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота".split("_"),isFormat:/\[ ?[Ууў] ?(?:мінулую|наступную)? ?\] ?dddd/},weekdaysShort:"нд_пн_ат_ср_чц_пт_сб".split("_"),weekdaysMin:"нд_пн_ат_ср_чц_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., HH:mm",LLLL:"dddd, D MMMM YYYY г., HH:mm"},calendar:{sameDay:"[Сёння ў] LT",nextDay:"[Заўтра ў] LT",lastDay:"[Учора ў] LT",nextWeek:function(){return"[У] dddd [ў] LT"},lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return"[У мінулую] dddd [ў] LT";case 1:case 2:case 4:return"[У мінулы] dddd [ў] LT"}},sameElse:"L"},relativeTime:{future:"праз %s",past:"%s таму",s:"некалькі секунд",m:t,mm:t,h:t,hh:t,d:"дзень",dd:t,M:"месяц",MM:t,y:"год",yy:t},meridiemParse:/ночы|раніцы|дня|вечара/,isPM:function(e){return/^(дня|вечара)$/.test(e)},meridiem:function(e,t,n){if(e<4)return"ночы";else if(e<12)return"раніцы";else if(e<17)return"дня";else return"вечара"},dayOfMonthOrdinalParse:/\d{1,2}-(і|ы|га)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":case"w":case"W":return(e%10===2||e%10===3)&&e%100!==12&&e%100!==13?e+"-і":e+"-ы";case"D":return e+"-га";default:return e}},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("bg",{months:"януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември".split("_"),monthsShort:"яну_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек".split("_"),weekdays:"неделя_понеделник_вторник_сряда_четвъртък_петък_събота".split("_"),weekdaysShort:"нед_пон_вто_сря_чет_пет_съб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Днес в] LT",nextDay:"[Утре в] LT",nextWeek:"dddd [в] LT",lastDay:"[Вчера в] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[Миналата] dddd [в] LT";case 1:case 2:case 4:case 5:return"[Миналия] dddd [в] LT"}},sameElse:"L"},relativeTime:{future:"след %s",past:"преди %s",s:"няколко секунди",ss:"%d секунди",m:"минута",mm:"%d минути",h:"час",hh:"%d часа",d:"ден",dd:"%d дена",w:"седмица",ww:"%d седмици",M:"месец",MM:"%d месеца",y:"година",yy:"%d години"},dayOfMonthOrdinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(e){var t=e%10,n=e%100;if(e===0)return e+"-ев";else if(n===0)return e+"-ен";else if(n>10&&n<20)return e+"-ти";else if(t===1)return e+"-ви";else if(t===2)return e+"-ри";else if(t===7||t===8)return e+"-ми";else return e+"-ти"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("bm",{months:"Zanwuyekalo_Fewuruyekalo_Marisikalo_Awirilikalo_Mɛkalo_Zuwɛnkalo_Zuluyekalo_Utikalo_Sɛtanburukalo_ɔkutɔburukalo_Nowanburukalo_Desanburukalo".split("_"),monthsShort:"Zan_Few_Mar_Awi_Mɛ_Zuw_Zul_Uti_Sɛt_ɔku_Now_Des".split("_"),weekdays:"Kari_Ntɛnɛn_Tarata_Araba_Alamisa_Juma_Sibiri".split("_"),weekdaysShort:"Kar_Ntɛ_Tar_Ara_Ala_Jum_Sib".split("_"),weekdaysMin:"Ka_Nt_Ta_Ar_Al_Ju_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"MMMM [tile] D [san] YYYY",LLL:"MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm",LLLL:"dddd MMMM [tile] D [san] YYYY [lɛrɛ] HH:mm"},calendar:{sameDay:"[Bi lɛrɛ] LT",nextDay:"[Sini lɛrɛ] LT",nextWeek:"dddd [don lɛrɛ] LT",lastDay:"[Kunu lɛrɛ] LT",lastWeek:"dddd [tɛmɛnen lɛrɛ] LT",sameElse:"L"},relativeTime:{future:"%s kɔnɔ",past:"a bɛ %s bɔ",s:"sanga dama dama",ss:"sekondi %d",m:"miniti kelen",mm:"miniti %d",h:"lɛrɛ kelen",hh:"lɛrɛ %d",d:"tile kelen",dd:"tile %d",M:"kalo kelen",MM:"kalo %d",y:"san kelen",yy:"san %d"},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},n={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"},a;e.defineLocale("bn",{months:"জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি".split("_"),weekdaysMin:"রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm সময়",LLLL:"dddd, D MMMM YYYY, A h:mm সময়"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কয়েক সেকেন্ড",ss:"%d সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(e){return e.replace(/[১২৩৪৫৬৭৮৯০]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/রাত|সকাল|দুপুর|বিকাল|রাত/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="রাত"&&e>=4||t==="দুপুর"&&e<5||t==="বিকাল")return e+12;else return e},meridiem:function(e,t,n){if(e<4)return"রাত";else if(e<10)return"সকাল";else if(e<17)return"দুপুর";else if(e<20)return"বিকাল";else return"রাত"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"১",2:"২",3:"৩",4:"৪",5:"৫",6:"৬",7:"৭",8:"৮",9:"৯",0:"০"},n={"১":"1","২":"2","৩":"3","৪":"4","৫":"5","৬":"6","৭":"7","৮":"8","৯":"9","০":"0"},a;e.defineLocale("bn-bd",{months:"জানুয়ারি_ফেব্রুয়ারি_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর".split("_"),monthsShort:"জানু_ফেব্রু_মার্চ_এপ্রিল_মে_জুন_জুলাই_আগস্ট_সেপ্ট_অক্টো_নভে_ডিসে".split("_"),weekdays:"রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পতিবার_শুক্রবার_শনিবার".split("_"),weekdaysShort:"রবি_সোম_মঙ্গল_বুধ_বৃহস্পতি_শুক্র_শনি".split("_"),weekdaysMin:"রবি_সোম_মঙ্গল_বুধ_বৃহ_শুক্র_শনি".split("_"),longDateFormat:{LT:"A h:mm সময়",LTS:"A h:mm:ss সময়",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm সময়",LLLL:"dddd, D MMMM YYYY, A h:mm সময়"},calendar:{sameDay:"[আজ] LT",nextDay:"[আগামীকাল] LT",nextWeek:"dddd, LT",lastDay:"[গতকাল] LT",lastWeek:"[গত] dddd, LT",sameElse:"L"},relativeTime:{future:"%s পরে",past:"%s আগে",s:"কয়েক সেকেন্ড",ss:"%d সেকেন্ড",m:"এক মিনিট",mm:"%d মিনিট",h:"এক ঘন্টা",hh:"%d ঘন্টা",d:"এক দিন",dd:"%d দিন",M:"এক মাস",MM:"%d মাস",y:"এক বছর",yy:"%d বছর"},preparse:function(e){return e.replace(/[১২৩৪৫৬৭৮৯০]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/রাত|ভোর|সকাল|দুপুর|বিকাল|সন্ধ্যা|রাত/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="রাত")return e<4?e:e+12;else if(t==="ভোর")return e;else if(t==="সকাল")return e;else if(t==="দুপুর")return e>=3?e:e+12;else if(t==="বিকাল")return e+12;else if(t==="সন্ধ্যা")return e+12},meridiem:function(e,t,n){if(e<4)return"রাত";else if(e<6)return"ভোর";else if(e<12)return"সকাল";else if(e<15)return"দুপুর";else if(e<18)return"বিকাল";else if(e<20)return"সন্ধ্যা";else return"রাত"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"༡",2:"༢",3:"༣",4:"༤",5:"༥",6:"༦",7:"༧",8:"༨",9:"༩",0:"༠"},n={"༡":"1","༢":"2","༣":"3","༤":"4","༥":"5","༦":"6","༧":"7","༨":"8","༩":"9","༠":"0"},a;e.defineLocale("bo",{months:"ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ".split("_"),monthsShort:"ཟླ་1_ཟླ་2_ཟླ་3_ཟླ་4_ཟླ་5_ཟླ་6_ཟླ་7_ཟླ་8_ཟླ་9_ཟླ་10_ཟླ་11_ཟླ་12".split("_"),monthsShortRegex:/^(ཟླ་\d{1,2})/,monthsParseExact:true,weekdays:"གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་".split("_"),weekdaysShort:"ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་".split("_"),weekdaysMin:"ཉི_ཟླ_མིག_ལྷག_ཕུར_སངས_སྤེན".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[དི་རིང] LT",nextDay:"[སང་ཉིན] LT",nextWeek:"[བདུན་ཕྲག་རྗེས་མ], LT",lastDay:"[ཁ་སང] LT",lastWeek:"[བདུན་ཕྲག་མཐའ་མ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ལ་",past:"%s སྔན་ལ",s:"ལམ་སང",ss:"%d སྐར་ཆ།",m:"སྐར་མ་གཅིག",mm:"%d སྐར་མ",h:"ཆུ་ཚོད་གཅིག",hh:"%d ཆུ་ཚོད",d:"ཉིན་གཅིག",dd:"%d ཉིན་",M:"ཟླ་བ་གཅིག",MM:"%d ཟླ་བ",y:"ལོ་གཅིག",yy:"%d ལོ"},preparse:function(e){return e.replace(/[༡༢༣༤༥༦༧༨༩༠]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="མཚན་མོ"&&e>=4||t==="ཉིན་གུང"&&e<5||t==="དགོང་དག")return e+12;else return e},meridiem:function(e,t,n){if(e<4)return"མཚན་མོ";else if(e<10)return"ཞོགས་ཀས";else if(e<17)return"ཉིན་གུང";else if(e<20)return"དགོང་དག";else return"མཚན་མོ"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n){var a={mm:"munutenn",MM:"miz",dd:"devezh"};return e+" "+r(a[n],e)}function n(e){switch(a(e)){case 1:case 3:case 4:case 5:case 9:return e+" bloaz";default:return e+" vloaz"}}function a(e){if(e>9)return a(e%10);return e}function r(e,t){if(t===2)return o(e);return e}function o(e){var t={m:"v",b:"v",d:"z"};if(t[e.charAt(0)]===undefined)return e;return t[e.charAt(0)]+e.substring(1)}var i=[/^gen/i,/^c[ʼ\']hwe/i,/^meu/i,/^ebr/i,/^mae/i,/^(mez|eve)/i,/^gou/i,/^eos/i,/^gwe/i,/^her/i,/^du/i,/^ker/i],s=/^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu|gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,l=/^(genver|c[ʼ\']hwevrer|meurzh|ebrel|mae|mezheven|gouere|eost|gwengolo|here|du|kerzu)/i,u=/^(gen|c[ʼ\']hwe|meu|ebr|mae|eve|gou|eos|gwe|her|du|ker)/i,c=[/^sul/i,/^lun/i,/^meurzh/i,/^merc[ʼ\']her/i,/^yaou/i,/^gwener/i,/^sadorn/i],d=[/^Sul/i,/^Lun/i,/^Meu/i,/^Mer/i,/^Yao/i,/^Gwe/i,/^Sad/i],f=[/^Su/i,/^Lu/i,/^Me([^r]|$)/i,/^Mer/i,/^Ya/i,/^Gw/i,/^Sa/i],p;e.defineLocale("br",{months:"Genver_Cʼhwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu".split("_"),monthsShort:"Gen_Cʼhwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker".split("_"),weekdays:"Sul_Lun_Meurzh_Mercʼher_Yaou_Gwener_Sadorn".split("_"),weekdaysShort:"Sul_Lun_Meu_Mer_Yao_Gwe_Sad".split("_"),weekdaysMin:"Su_Lu_Me_Mer_Ya_Gw_Sa".split("_"),weekdaysParse:f,fullWeekdaysParse:c,shortWeekdaysParse:d,minWeekdaysParse:f,monthsRegex:s,monthsShortRegex:s,monthsStrictRegex:l,monthsShortStrictRegex:u,monthsParse:i,longMonthsParse:i,shortMonthsParse:i,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [a viz] MMMM YYYY",LLL:"D [a viz] MMMM YYYY HH:mm",LLLL:"dddd, D [a viz] MMMM YYYY HH:mm"},calendar:{sameDay:"[Hiziv da] LT",nextDay:"[Warcʼhoazh da] LT",nextWeek:"dddd [da] LT",lastDay:"[Decʼh da] LT",lastWeek:"dddd [paset da] LT",sameElse:"L"},relativeTime:{future:"a-benn %s",past:"%s ʼzo",s:"un nebeud segondennoù",ss:"%d eilenn",m:"ur vunutenn",mm:t,h:"un eur",hh:"%d eur",d:"un devezh",dd:t,M:"ur miz",MM:t,y:"ur bloaz",yy:n},dayOfMonthOrdinalParse:/\d{1,2}(añ|vet)/,ordinal:function(e){var t=e===1?"añ":"vet";return e+t},week:{dow:1,doy:4},meridiemParse:/a.m.|g.m./,isPM:function(e){return e==="g.m."},meridiem:function(e,t,n){return e<12?"a.m.":"g.m."}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n){var a=e+" ";switch(n){case"ss":if(e===1)a+="sekunda";else if(e===2||e===3||e===4)a+="sekunde";else a+="sekundi";return a;case"m":return t?"jedna minuta":"jedne minute";case"mm":if(e===1)a+="minuta";else if(e===2||e===3||e===4)a+="minute";else a+="minuta";return a;case"h":return t?"jedan sat":"jednog sata";case"hh":if(e===1)a+="sat";else if(e===2||e===3||e===4)a+="sata";else a+="sati";return a;case"dd":if(e===1)a+="dan";else a+="dana";return a;case"MM":if(e===1)a+="mjesec";else if(e===2||e===3||e===4)a+="mjeseca";else a+="mjeseci";return a;case"yy":if(e===1)a+="godina";else if(e===2||e===3||e===4)a+="godine";else a+="godina";return a}}var n;e.defineLocale("bs",{months:"januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.".split("_"),monthsParseExact:true,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:case 3:return"[prošlu] dddd [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:t,m:t,mm:t,h:t,hh:t,d:"dan",dd:t,M:"mjesec",MM:t,y:"godinu",yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ca",{months:{standalone:"gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre".split("_"),format:"de gener_de febrer_de març_d'abril_de maig_de juny_de juliol_d'agost_de setembre_d'octubre_de novembre_de desembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._març_abr._maig_juny_jul._ag._set._oct._nov._des.".split("_"),monthsParseExact:true,weekdays:"diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dt._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dt_dc_dj_dv_ds".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a les] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a les] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:function(){return"[avui a "+(this.hours()!==1?"les":"la")+"] LT"},nextDay:function(){return"[demà a "+(this.hours()!==1?"les":"la")+"] LT"},nextWeek:function(){return"dddd [a "+(this.hours()!==1?"les":"la")+"] LT"},lastDay:function(){return"[ahir a "+(this.hours()!==1?"les":"la")+"] LT"},lastWeek:function(){return"[el] dddd [passat a "+(this.hours()!==1?"les":"la")+"] LT"},sameElse:"L"},relativeTime:{future:"d'aquí %s",past:"fa %s",s:"uns segons",ss:"%d segons",m:"un minut",mm:"%d minuts",h:"una hora",hh:"%d hores",d:"un dia",dd:"%d dies",M:"un mes",MM:"%d mesos",y:"un any",yy:"%d anys"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(e,t){var n=e===1?"r":e===2?"n":e===3?"r":e===4?"t":"è";if(t==="w"||t==="W")n="a";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={format:"leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec".split("_"),standalone:"ledna_února_března_dubna_května_června_července_srpna_září_října_listopadu_prosince".split("_")},n="led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro".split("_"),a=[/^led/i,/^úno/i,/^bře/i,/^dub/i,/^kvě/i,/^(čvn|červen$|června)/i,/^(čvc|červenec|července)/i,/^srp/i,/^zář/i,/^říj/i,/^lis/i,/^pro/i],r=/^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i,o;function i(e){return e>1&&e<5&&~~(e/10)!==1}function s(e,t,n,a){var r=e+" ";switch(n){case"s":return t||a?"pár sekund":"pár sekundami";case"ss":if(t||a)return r+(i(e)?"sekundy":"sekund");else return r+"sekundami";case"m":return t?"minuta":a?"minutu":"minutou";case"mm":if(t||a)return r+(i(e)?"minuty":"minut");else return r+"minutami";case"h":return t?"hodina":a?"hodinu":"hodinou";case"hh":if(t||a)return r+(i(e)?"hodiny":"hodin");else return r+"hodinami";case"d":return t||a?"den":"dnem";case"dd":if(t||a)return r+(i(e)?"dny":"dní");else return r+"dny";case"M":return t||a?"měsíc":"měsícem";case"MM":if(t||a)return r+(i(e)?"měsíce":"měsíců");else return r+"měsíci";case"y":return t||a?"rok":"rokem";case"yy":if(t||a)return r+(i(e)?"roky":"let");else return r+"lety"}}e.defineLocale("cs",{months:t,monthsShort:n,monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i,monthsShortStrictRegex:/^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i,monthsParse:a,longMonthsParse:a,shortMonthsParse:a,weekdays:"neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota".split("_"),weekdaysShort:"ne_po_út_st_čt_pá_so".split("_"),weekdaysMin:"ne_po_út_st_čt_pá_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm",l:"D. M. YYYY"},calendar:{sameDay:"[dnes v] LT",nextDay:"[zítra v] LT",nextWeek:function(){switch(this.day()){case 0:return"[v neděli v] LT";case 1:case 2:return"[v] dddd [v] LT";case 3:return"[ve středu v] LT";case 4:return"[ve čtvrtek v] LT";case 5:return"[v pátek v] LT";case 6:return"[v sobotu v] LT"}},lastDay:"[včera v] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulou neděli v] LT";case 1:case 2:return"[minulé] dddd [v] LT";case 3:return"[minulou středu v] LT";case 4:case 5:return"[minulý] dddd [v] LT";case 6:return"[minulou sobotu v] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"před %s",s:s,ss:s,m:s,mm:s,h:s,hh:s,d:s,dd:s,M:s,MM:s,y:s,yy:s},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("cv",{months:"кӑрлач_нарӑс_пуш_ака_май_ҫӗртме_утӑ_ҫурла_авӑн_юпа_чӳк_раштав".split("_"),monthsShort:"кӑр_нар_пуш_ака_май_ҫӗр_утӑ_ҫур_авн_юпа_чӳк_раш".split("_"),weekdays:"вырсарникун_тунтикун_ытларикун_юнкун_кӗҫнерникун_эрнекун_шӑматкун".split("_"),weekdaysShort:"выр_тун_ытл_юн_кӗҫ_эрн_шӑм".split("_"),weekdaysMin:"вр_тн_ыт_юн_кҫ_эр_шм".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ]",LLL:"YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm",LLLL:"dddd, YYYY [ҫулхи] MMMM [уйӑхӗн] D[-мӗшӗ], HH:mm"},calendar:{sameDay:"[Паян] LT [сехетре]",nextDay:"[Ыран] LT [сехетре]",lastDay:"[Ӗнер] LT [сехетре]",nextWeek:"[Ҫитес] dddd LT [сехетре]",lastWeek:"[Иртнӗ] dddd LT [сехетре]",sameElse:"L"},relativeTime:{future:function(e){var t=/сехет$/i.exec(e)?"рен":/ҫул$/i.exec(e)?"тан":"ран";return e+t},past:"%s каялла",s:"пӗр-ик ҫеккунт",ss:"%d ҫеккунт",m:"пӗр минут",mm:"%d минут",h:"пӗр сехет",hh:"%d сехет",d:"пӗр кун",dd:"%d кун",M:"пӗр уйӑх",MM:"%d уйӑх",y:"пӗр ҫул",yy:"%d ҫул"},dayOfMonthOrdinalParse:/\d{1,2}-мӗш/,ordinal:"%d-мӗш",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("cy",{months:"Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr".split("_"),monthsShort:"Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag".split("_"),weekdays:"Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn".split("_"),weekdaysShort:"Sul_Llun_Maw_Mer_Iau_Gwe_Sad".split("_"),weekdaysMin:"Su_Ll_Ma_Me_Ia_Gw_Sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Heddiw am] LT",nextDay:"[Yfory am] LT",nextWeek:"dddd [am] LT",lastDay:"[Ddoe am] LT",lastWeek:"dddd [diwethaf am] LT",sameElse:"L"},relativeTime:{future:"mewn %s",past:"%s yn ôl",s:"ychydig eiliadau",ss:"%d eiliad",m:"munud",mm:"%d munud",h:"awr",hh:"%d awr",d:"diwrnod",dd:"%d diwrnod",M:"mis",MM:"%d mis",y:"blwyddyn",yy:"%d flynedd"},dayOfMonthOrdinalParse:/\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,ordinal:function(e){var t=e,n="",a=["","af","il","ydd","ydd","ed","ed","ed","fed","fed","fed","eg","fed","eg","eg","fed","eg","eg","fed","eg","fed"];if(t>20)if(t===40||t===50||t===60||t===80||t===100)n="fed";else n="ain";else if(t>0)n=a[t];return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("da",{months:"januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"søn_man_tir_ons_tor_fre_lør".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd [d.] D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"på dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[i] dddd[s kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"få sekunder",ss:"%d sekunder",m:"et minut",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dage",M:"en måned",MM:"%d måneder",y:"et år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return t?r[n][0]:r[n][1]}var n;e.defineLocale("de",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:true,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,w:t,ww:"%d Wochen",M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return t?r[n][0]:r[n][1]}var n;e.defineLocale("de-at",{months:"Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jän._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:true,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So._Mo._Di._Mi._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,w:t,ww:"%d Wochen",M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={m:["eine Minute","einer Minute"],h:["eine Stunde","einer Stunde"],d:["ein Tag","einem Tag"],dd:[e+" Tage",e+" Tagen"],w:["eine Woche","einer Woche"],M:["ein Monat","einem Monat"],MM:[e+" Monate",e+" Monaten"],y:["ein Jahr","einem Jahr"],yy:[e+" Jahre",e+" Jahren"]};return t?r[n][0]:r[n][1]}var n;e.defineLocale("de-ch",{months:"Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.".split("_"),monthsParseExact:true,weekdays:"Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag".split("_"),weekdaysShort:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysMin:"So_Mo_Di_Mi_Do_Fr_Sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY HH:mm",LLLL:"dddd, D. MMMM YYYY HH:mm"},calendar:{sameDay:"[heute um] LT [Uhr]",sameElse:"L",nextDay:"[morgen um] LT [Uhr]",nextWeek:"dddd [um] LT [Uhr]",lastDay:"[gestern um] LT [Uhr]",lastWeek:"[letzten] dddd [um] LT [Uhr]"},relativeTime:{future:"in %s",past:"vor %s",s:"ein paar Sekunden",ss:"%d Sekunden",m:t,mm:"%d Minuten",h:t,hh:"%d Stunden",d:t,dd:t,w:t,ww:"%d Wochen",M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t=["ޖެނުއަރީ","ފެބްރުއަރީ","މާރިޗު","އޭޕްރީލު","މޭ","ޖޫން","ޖުލައި","އޯގަސްޓު","ސެޕްޓެމްބަރު","އޮކްޓޯބަރު","ނޮވެމްބަރު","ޑިސެމްބަރު"],n=["އާދިއްތަ","ހޯމަ","އަންގާރަ","ބުދަ","ބުރާސްފަތި","ހުކުރު","ހޮނިހިރު"],a;e.defineLocale("dv",{months:t,monthsShort:t,weekdays:n,weekdaysShort:n,weekdaysMin:"އާދި_ހޯމަ_އަން_ބުދަ_ބުރާ_ހުކު_ހޮނި".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"D/M/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},meridiemParse:/މކ|މފ/,isPM:function(e){return"މފ"===e},meridiem:function(e,t,n){if(e<12)return"މކ";else return"މފ"},calendar:{sameDay:"[މިއަދު] LT",nextDay:"[މާދަމާ] LT",nextWeek:"dddd LT",lastDay:"[އިއްޔެ] LT",lastWeek:"[ފާއިތުވި] dddd LT",sameElse:"L"},relativeTime:{future:"ތެރޭގައި %s",past:"ކުރިން %s",s:"ސިކުންތުކޮޅެއް",ss:"d% ސިކުންތު",m:"މިނިޓެއް",mm:"މިނިޓު %d",h:"ގަޑިއިރެއް",hh:"ގަޑިއިރު %d",d:"ދުވަހެއް",dd:"ދުވަސް %d",M:"މަހެއް",MM:"މަސް %d",y:"އަހަރެއް",yy:"އަހަރު %d"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:7,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function r(e){return typeof Function!=="undefined"&&e instanceof Function||Object.prototype.toString.call(e)==="[object Function]"}var t;e.defineLocale("el",{monthsNominativeEl:"Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος".split("_"),monthsGenitiveEl:"Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου".split("_"),months:function(e,t){if(!e)return this._monthsNominativeEl;else if(typeof t==="string"&&/D/.test(t.substring(0,t.indexOf("MMMM"))))return this._monthsGenitiveEl[e.month()];else return this._monthsNominativeEl[e.month()]},monthsShort:"Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ".split("_"),weekdays:"Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο".split("_"),weekdaysShort:"Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ".split("_"),weekdaysMin:"Κυ_Δε_Τρ_Τε_Πε_Πα_Σα".split("_"),meridiem:function(e,t,n){if(e>11)return n?"μμ":"ΜΜ";else return n?"πμ":"ΠΜ"},isPM:function(e){return(e+"").toLowerCase()[0]==="μ"},meridiemParse:/[ΠΜ]\.?Μ?\.?/i,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendarEl:{sameDay:"[Σήμερα {}] LT",nextDay:"[Αύριο {}] LT",nextWeek:"dddd [{}] LT",lastDay:"[Χθες {}] LT",lastWeek:function(){switch(this.day()){case 6:return"[το προηγούμενο] dddd [{}] LT";default:return"[την προηγούμενη] dddd [{}] LT"}},sameElse:"L"},calendar:function(e,t){var n=this._calendarEl[e],a=t&&t.hours();if(r(n))n=n.apply(t);return n.replace("{}",a%12===1?"στη":"στις")},relativeTime:{future:"σε %s",past:"%s πριν",s:"λίγα δευτερόλεπτα",ss:"%d δευτερόλεπτα",m:"ένα λεπτό",mm:"%d λεπτά",h:"μία ώρα",hh:"%d ώρες",d:"μία μέρα",dd:"%d μέρες",M:"ένας μήνας",MM:"%d μήνες",y:"ένας χρόνος",yy:"%d χρόνια"},dayOfMonthOrdinalParse:/\d{1,2}η/,ordinal:"%dη",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-au",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:0,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-ca",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"YYYY-MM-DD",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-gb",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-ie",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-il",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-in",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-nz",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("en-sg",{months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("eo",{months:"januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro".split("_"),monthsShort:"jan_feb_mart_apr_maj_jun_jul_aŭg_sept_okt_nov_dec".split("_"),weekdays:"dimanĉo_lundo_mardo_merkredo_ĵaŭdo_vendredo_sabato".split("_"),weekdaysShort:"dim_lun_mard_merk_ĵaŭ_ven_sab".split("_"),weekdaysMin:"di_lu_ma_me_ĵa_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"[la] D[-an de] MMMM, YYYY",LLL:"[la] D[-an de] MMMM, YYYY HH:mm",LLLL:"dddd[n], [la] D[-an de] MMMM, YYYY HH:mm",llll:"ddd, [la] D[-an de] MMM, YYYY HH:mm"},meridiemParse:/[ap]\.t\.m/i,isPM:function(e){return e.charAt(0).toLowerCase()==="p"},meridiem:function(e,t,n){if(e>11)return n?"p.t.m.":"P.T.M.";else return n?"a.t.m.":"A.T.M."},calendar:{sameDay:"[Hodiaŭ je] LT",nextDay:"[Morgaŭ je] LT",nextWeek:"dddd[n je] LT",lastDay:"[Hieraŭ je] LT",lastWeek:"[pasintan] dddd[n je] LT",sameElse:"L"},relativeTime:{future:"post %s",past:"antaŭ %s",s:"kelkaj sekundoj",ss:"%d sekundoj",m:"unu minuto",mm:"%d minutoj",h:"unu horo",hh:"%d horoj",d:"unu tago",dd:"%d tagoj",M:"unu monato",MM:"%d monatoj",y:"unu jaro",yy:"%d jaroj"},dayOfMonthOrdinalParse:/\d{1,2}a/,ordinal:"%da",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),a="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),t=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,o;e.defineLocale("es",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(this.hours()!==1?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(this.hours()!==1?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(this.hours()!==1?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(this.hours()!==1?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(this.hours()!==1?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4},invalidDate:"Fecha inválida"})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),a="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),t=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,o;e.defineLocale("es-do",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(this.hours()!==1?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(this.hours()!==1?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(this.hours()!==1?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(this.hours()!==1?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(this.hours()!==1?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),a="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),t=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,o;e.defineLocale("es-mx",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoy a la"+(this.hours()!==1?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(this.hours()!==1?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(this.hours()!==1?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(this.hours()!==1?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(this.hours()!==1?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:0,doy:4},invalidDate:"Fecha inválida"})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.".split("_"),a="ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic".split("_"),t=[/^ene/i,/^feb/i,/^mar/i,/^abr/i,/^may/i,/^jun/i,/^jul/i,/^ago/i,/^sep/i,/^oct/i,/^nov/i,/^dic/i],r=/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,o;e.defineLocale("es-us",{months:"enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,monthsShortStrictRegex:/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"domingo_lunes_martes_miércoles_jueves_viernes_sábado".split("_"),weekdaysShort:"dom._lun._mar._mié._jue._vie._sáb.".split("_"),weekdaysMin:"do_lu_ma_mi_ju_vi_sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"MM/DD/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY h:mm A",LLLL:"dddd, D [de] MMMM [de] YYYY h:mm A"},calendar:{sameDay:function(){return"[hoy a la"+(this.hours()!==1?"s":"")+"] LT"},nextDay:function(){return"[mañana a la"+(this.hours()!==1?"s":"")+"] LT"},nextWeek:function(){return"dddd [a la"+(this.hours()!==1?"s":"")+"] LT"},lastDay:function(){return"[ayer a la"+(this.hours()!==1?"s":"")+"] LT"},lastWeek:function(){return"[el] dddd [pasado a la"+(this.hours()!==1?"s":"")+"] LT"},sameElse:"L"},relativeTime:{future:"en %s",past:"hace %s",s:"unos segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"una hora",hh:"%d horas",d:"un día",dd:"%d días",w:"una semana",ww:"%d semanas",M:"un mes",MM:"%d meses",y:"un año",yy:"%d años"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={s:["mõne sekundi","mõni sekund","paar sekundit"],ss:[e+"sekundi",e+"sekundit"],m:["ühe minuti","üks minut"],mm:[e+" minuti",e+" minutit"],h:["ühe tunni","tund aega","üks tund"],hh:[e+" tunni",e+" tundi"],d:["ühe päeva","üks päev"],M:["kuu aja","kuu aega","üks kuu"],MM:[e+" kuu",e+" kuud"],y:["ühe aasta","aasta","üks aasta"],yy:[e+" aasta",e+" aastat"]};if(t)return r[n][2]?r[n][2]:r[n][1];return a?r[n][0]:r[n][1]}var n;e.defineLocale("et",{months:"jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember".split("_"),monthsShort:"jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets".split("_"),weekdays:"pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev".split("_"),weekdaysShort:"P_E_T_K_N_R_L".split("_"),weekdaysMin:"P_E_T_K_N_R_L".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[Täna,] LT",nextDay:"[Homme,] LT",nextWeek:"[Järgmine] dddd LT",lastDay:"[Eile,] LT",lastWeek:"[Eelmine] dddd LT",sameElse:"L"},relativeTime:{future:"%s pärast",past:"%s tagasi",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:"%d päeva",M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("eu",{months:"urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua".split("_"),monthsShort:"urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.".split("_"),monthsParseExact:true,weekdays:"igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata".split("_"),weekdaysShort:"ig._al._ar._az._og._ol._lr.".split("_"),weekdaysMin:"ig_al_ar_az_og_ol_lr".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY[ko] MMMM[ren] D[a]",LLL:"YYYY[ko] MMMM[ren] D[a] HH:mm",LLLL:"dddd, YYYY[ko] MMMM[ren] D[a] HH:mm",l:"YYYY-M-D",ll:"YYYY[ko] MMM D[a]",lll:"YYYY[ko] MMM D[a] HH:mm",llll:"ddd, YYYY[ko] MMM D[a] HH:mm"},calendar:{sameDay:"[gaur] LT[etan]",nextDay:"[bihar] LT[etan]",nextWeek:"dddd LT[etan]",lastDay:"[atzo] LT[etan]",lastWeek:"[aurreko] dddd LT[etan]",sameElse:"L"},relativeTime:{future:"%s barru",past:"duela %s",s:"segundo batzuk",ss:"%d segundo",m:"minutu bat",mm:"%d minutu",h:"ordu bat",hh:"%d ordu",d:"egun bat",dd:"%d egun",M:"hilabete bat",MM:"%d hilabete",y:"urte bat",yy:"%d urte"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"۱",2:"۲",3:"۳",4:"۴",5:"۵",6:"۶",7:"۷",8:"۸",9:"۹",0:"۰"},n={"۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","۰":"0"},a;e.defineLocale("fa",{months:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),monthsShort:"ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر".split("_"),weekdays:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysShort:"یک‌شنبه_دوشنبه_سه‌شنبه_چهارشنبه_پنج‌شنبه_جمعه_شنبه".split("_"),weekdaysMin:"ی_د_س_چ_پ_ج_ش".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/قبل از ظهر|بعد از ظهر/,isPM:function(e){return/بعد از ظهر/.test(e)},meridiem:function(e,t,n){if(e<12)return"قبل از ظهر";else return"بعد از ظهر"},calendar:{sameDay:"[امروز ساعت] LT",nextDay:"[فردا ساعت] LT",nextWeek:"dddd [ساعت] LT",lastDay:"[دیروز ساعت] LT",lastWeek:"dddd [پیش] [ساعت] LT",sameElse:"L"},relativeTime:{future:"در %s",past:"%s پیش",s:"چند ثانیه",ss:"%d ثانیه",m:"یک دقیقه",mm:"%d دقیقه",h:"یک ساعت",hh:"%d ساعت",d:"یک روز",dd:"%d روز",M:"یک ماه",MM:"%d ماه",y:"یک سال",yy:"%d سال"},preparse:function(e){return e.replace(/[۰-۹]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},dayOfMonthOrdinalParse:/\d{1,2}م/,ordinal:"%dم",week:{dow:6,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän".split(" "),a=["nolla","yhden","kahden","kolmen","neljän","viiden","kuuden",n[7],n[8],n[9]],t;function r(e,t,n,a){var r="";switch(n){case"s":return a?"muutaman sekunnin":"muutama sekunti";case"ss":r=a?"sekunnin":"sekuntia";break;case"m":return a?"minuutin":"minuutti";case"mm":r=a?"minuutin":"minuuttia";break;case"h":return a?"tunnin":"tunti";case"hh":r=a?"tunnin":"tuntia";break;case"d":return a?"päivän":"päivä";case"dd":r=a?"päivän":"päivää";break;case"M":return a?"kuukauden":"kuukausi";case"MM":r=a?"kuukauden":"kuukautta";break;case"y":return a?"vuoden":"vuosi";case"yy":r=a?"vuoden":"vuotta";break}r=o(e,a)+" "+r;return r}function o(e,t){return e<10?t?a[e]:n[e]:e}e.defineLocale("fi",{months:"tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu".split("_"),monthsShort:"tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu".split("_"),weekdays:"sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai".split("_"),weekdaysShort:"su_ma_ti_ke_to_pe_la".split("_"),weekdaysMin:"su_ma_ti_ke_to_pe_la".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"Do MMMM[ta] YYYY",LLL:"Do MMMM[ta] YYYY, [klo] HH.mm",LLLL:"dddd, Do MMMM[ta] YYYY, [klo] HH.mm",l:"D.M.YYYY",ll:"Do MMM YYYY",lll:"Do MMM YYYY, [klo] HH.mm",llll:"ddd, Do MMM YYYY, [klo] HH.mm"},calendar:{sameDay:"[tänään] [klo] LT",nextDay:"[huomenna] [klo] LT",nextWeek:"dddd [klo] LT",lastDay:"[eilen] [klo] LT",lastWeek:"[viime] dddd[na] [klo] LT",sameElse:"L"},relativeTime:{future:"%s päästä",past:"%s sitten",s:r,ss:r,m:r,mm:r,h:r,hh:r,d:r,dd:r,M:r,MM:r,y:r,yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("fil",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("fo",{months:"januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),weekdays:"sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur".split("_"),weekdaysShort:"sun_mán_týs_mik_hós_frí_ley".split("_"),weekdaysMin:"su_má_tý_mi_hó_fr_le".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D. MMMM, YYYY HH:mm"},calendar:{sameDay:"[Í dag kl.] LT",nextDay:"[Í morgin kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[Í gjár kl.] LT",lastWeek:"[síðstu] dddd [kl] LT",sameElse:"L"},relativeTime:{future:"um %s",past:"%s síðani",s:"fá sekund",ss:"%d sekundir",m:"ein minuttur",mm:"%d minuttir",h:"ein tími",hh:"%d tímar",d:"ein dagur",dd:"%d dagar",M:"ein mánaður",MM:"%d mánaðir",y:"eitt ár",yy:"%d ár"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t=/^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,n=/(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,a=/(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,r=[/^janv/i,/^févr/i,/^mars/i,/^avr/i,/^mai/i,/^juin/i,/^juil/i,/^août/i,/^sept/i,/^oct/i,/^nov/i,/^déc/i],o;e.defineLocale("fr",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsRegex:a,monthsShortRegex:a,monthsStrictRegex:t,monthsShortStrictRegex:n,monthsParse:r,longMonthsParse:r,shortMonthsParse:r,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd’hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",w:"une semaine",ww:"%d semaines",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|)/,ordinal:function(e,t){switch(t){case"D":return e+(e===1?"er":"");default:case"M":case"Q":case"DDD":case"d":return e+(e===1?"er":"e");case"w":case"W":return e+(e===1?"re":"e")}},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("fr-ca",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:true,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd’hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(e,t){switch(t){default:case"M":case"Q":case"D":case"DDD":case"d":return e+(e===1?"er":"e");case"w":case"W":return e+(e===1?"re":"e")}}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("fr-ch",{months:"janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),monthsShort:"janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),monthsParseExact:true,weekdays:"dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),weekdaysShort:"dim._lun._mar._mer._jeu._ven._sam.".split("_"),weekdaysMin:"di_lu_ma_me_je_ve_sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Aujourd’hui à] LT",nextDay:"[Demain à] LT",nextWeek:"dddd [à] LT",lastDay:"[Hier à] LT",lastWeek:"dddd [dernier à] LT",sameElse:"L"},relativeTime:{future:"dans %s",past:"il y a %s",s:"quelques secondes",ss:"%d secondes",m:"une minute",mm:"%d minutes",h:"une heure",hh:"%d heures",d:"un jour",dd:"%d jours",M:"un mois",MM:"%d mois",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(er|e)/,ordinal:function(e,t){switch(t){default:case"M":case"Q":case"D":case"DDD":case"d":return e+(e===1?"er":"e");case"w":case"W":return e+(e===1?"re":"e")}},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.".split("_"),a="jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des".split("_"),t;e.defineLocale("fy",{months:"jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsParseExact:true,weekdays:"snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon".split("_"),weekdaysShort:"si._mo._ti._wo._to._fr._so.".split("_"),weekdaysMin:"Si_Mo_Ti_Wo_To_Fr_So".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[hjoed om] LT",nextDay:"[moarn om] LT",nextWeek:"dddd [om] LT",lastDay:"[juster om] LT",lastWeek:"[ôfrûne] dddd [om] LT",sameElse:"L"},relativeTime:{future:"oer %s",past:"%s lyn",s:"in pear sekonden",ss:"%d sekonden",m:"ien minút",mm:"%d minuten",h:"ien oere",hh:"%d oeren",d:"ien dei",dd:"%d dagen",M:"ien moanne",MM:"%d moannen",y:"ien jier",yy:"%d jierren"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(e===1||e===8||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t,n,a,r,o,i;e.defineLocale("ga",{months:["Eanáir","Feabhra","Márta","Aibreán","Bealtaine","Meitheamh","Iúil","Lúnasa","Meán Fómhair","Deireadh Fómhair","Samhain","Nollaig"],monthsShort:["Ean","Feabh","Márt","Aib","Beal","Meith","Iúil","Lún","M.F.","D.F.","Samh","Noll"],monthsParseExact:true,weekdays:["Dé Domhnaigh","Dé Luain","Dé Máirt","Dé Céadaoin","Déardaoin","Dé hAoine","Dé Sathairn"],weekdaysShort:["Domh","Luan","Máirt","Céad","Déar","Aoine","Sath"],weekdaysMin:["Do","Lu","Má","Cé","Dé","A","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Inniu ag] LT",nextDay:"[Amárach ag] LT",nextWeek:"dddd [ag] LT",lastDay:"[Inné ag] LT",lastWeek:"dddd [seo caite] [ag] LT",sameElse:"L"},relativeTime:{future:"i %s",past:"%s ó shin",s:"cúpla soicind",ss:"%d soicind",m:"nóiméad",mm:"%d nóiméad",h:"uair an chloig",hh:"%d uair an chloig",d:"lá",dd:"%d lá",M:"mí",MM:"%d míonna",y:"bliain",yy:"%d bliain"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(e){var t=e===1?"d":e%10===2?"na":"mh";return e+t},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t,n,a,r,o,i;e.defineLocale("gd",{months:["Am Faoilleach","An Gearran","Am Màrt","An Giblean","An Cèitean","An t-Ògmhios","An t-Iuchar","An Lùnastal","An t-Sultain","An Dàmhair","An t-Samhain","An Dùbhlachd"],monthsShort:["Faoi","Gear","Màrt","Gibl","Cèit","Ògmh","Iuch","Lùn","Sult","Dàmh","Samh","Dùbh"],monthsParseExact:true,weekdays:["Didòmhnaich","Diluain","Dimàirt","Diciadain","Diardaoin","Dihaoine","Disathairne"],weekdaysShort:["Did","Dil","Dim","Dic","Dia","Dih","Dis"],weekdaysMin:["Dò","Lu","Mà","Ci","Ar","Ha","Sa"],longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[An-diugh aig] LT",nextDay:"[A-màireach aig] LT",nextWeek:"dddd [aig] LT",lastDay:"[An-dè aig] LT",lastWeek:"dddd [seo chaidh] [aig] LT",sameElse:"L"},relativeTime:{future:"ann an %s",past:"bho chionn %s",s:"beagan diogan",ss:"%d diogan",m:"mionaid",mm:"%d mionaidean",h:"uair",hh:"%d uairean",d:"latha",dd:"%d latha",M:"mìos",MM:"%d mìosan",y:"bliadhna",yy:"%d bliadhna"},dayOfMonthOrdinalParse:/\d{1,2}(d|na|mh)/,ordinal:function(e){var t=e===1?"d":e%10===2?"na":"mh";return e+t},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("gl",{months:"xaneiro_febreiro_marzo_abril_maio_xuño_xullo_agosto_setembro_outubro_novembro_decembro".split("_"),monthsShort:"xan._feb._mar._abr._mai._xuñ._xul._ago._set._out._nov._dec.".split("_"),monthsParseExact:true,weekdays:"domingo_luns_martes_mércores_xoves_venres_sábado".split("_"),weekdaysShort:"dom._lun._mar._mér._xov._ven._sáb.".split("_"),weekdaysMin:"do_lu_ma_mé_xo_ve_sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY H:mm",LLLL:"dddd, D [de] MMMM [de] YYYY H:mm"},calendar:{sameDay:function(){return"[hoxe "+(this.hours()!==1?"ás":"á")+"] LT"},nextDay:function(){return"[mañá "+(this.hours()!==1?"ás":"á")+"] LT"},nextWeek:function(){return"dddd ["+(this.hours()!==1?"ás":"a")+"] LT"},lastDay:function(){return"[onte "+(this.hours()!==1?"á":"a")+"] LT"},lastWeek:function(){return"[o] dddd [pasado "+(this.hours()!==1?"ás":"a")+"] LT"},sameElse:"L"},relativeTime:{future:function(e){if(e.indexOf("un")===0)return"n"+e;return"en "+e},past:"hai %s",s:"uns segundos",ss:"%d segundos",m:"un minuto",mm:"%d minutos",h:"unha hora",hh:"%d horas",d:"un día",dd:"%d días",M:"un mes",MM:"%d meses",y:"un ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={s:["थोडया सॅकंडांनी","थोडे सॅकंड"],ss:[e+" सॅकंडांनी",e+" सॅकंड"],m:["एका मिणटान","एक मिनूट"],mm:[e+" मिणटांनी",e+" मिणटां"],h:["एका वरान","एक वर"],hh:[e+" वरांनी",e+" वरां"],d:["एका दिसान","एक दीस"],dd:[e+" दिसांनी",e+" दीस"],M:["एका म्हयन्यान","एक म्हयनो"],MM:[e+" म्हयन्यानी",e+" म्हयने"],y:["एका वर्सान","एक वर्स"],yy:[e+" वर्सांनी",e+" वर्सां"]};return a?r[n][0]:r[n][1]}var n;e.defineLocale("gom-deva",{months:{standalone:"जानेवारी_फेब्रुवारी_मार्च_एप्रील_मे_जून_जुलय_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर".split("_"),format:"जानेवारीच्या_फेब्रुवारीच्या_मार्चाच्या_एप्रीलाच्या_मेयाच्या_जूनाच्या_जुलयाच्या_ऑगस्टाच्या_सप्टेंबराच्या_ऑक्टोबराच्या_नोव्हेंबराच्या_डिसेंबराच्या".split("_"),isFormat:/MMMM(\s)+D[oD]?/},monthsShort:"जाने._फेब्रु._मार्च_एप्री._मे_जून_जुल._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.".split("_"),monthsParseExact:true,weekdays:"आयतार_सोमार_मंगळार_बुधवार_बिरेस्तार_सुक्रार_शेनवार".split("_"),weekdaysShort:"आयत._सोम._मंगळ._बुध._ब्रेस्त._सुक्र._शेन.".split("_"),weekdaysMin:"आ_सो_मं_बु_ब्रे_सु_शे".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"A h:mm [वाजतां]",LTS:"A h:mm:ss [वाजतां]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [वाजतां]",LLLL:"dddd, MMMM Do, YYYY, A h:mm [वाजतां]",llll:"ddd, D MMM YYYY, A h:mm [वाजतां]"},calendar:{sameDay:"[आयज] LT",nextDay:"[फाल्यां] LT",nextWeek:"[फुडलो] dddd[,] LT",lastDay:"[काल] LT",lastWeek:"[फाटलो] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s आदीं",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}(वेर)/,ordinal:function(e,t){switch(t){case"D":return e+"वेर";default:case"M":case"Q":case"DDD":case"d":case"w":case"W":return e}},week:{dow:0,doy:3},meridiemParse:/राती|सकाळीं|दनपारां|सांजे/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="राती")return e<4?e:e+12;else if(t==="सकाळीं")return e;else if(t==="दनपारां")return e>12?e:e+12;else if(t==="सांजे")return e+12},meridiem:function(e,t,n){if(e<4)return"राती";else if(e<12)return"सकाळीं";else if(e<16)return"दनपारां";else if(e<20)return"सांजे";else return"राती"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={s:["thoddea sekondamni","thodde sekond"],ss:[e+" sekondamni",e+" sekond"],m:["eka mintan","ek minut"],mm:[e+" mintamni",e+" mintam"],h:["eka voran","ek vor"],hh:[e+" voramni",e+" voram"],d:["eka disan","ek dis"],dd:[e+" disamni",e+" dis"],M:["eka mhoinean","ek mhoino"],MM:[e+" mhoineamni",e+" mhoine"],y:["eka vorsan","ek voros"],yy:[e+" vorsamni",e+" vorsam"]};return a?r[n][0]:r[n][1]}var n;e.defineLocale("gom-latn",{months:{standalone:"Janer_Febrer_Mars_Abril_Mai_Jun_Julai_Agost_Setembr_Otubr_Novembr_Dezembr".split("_"),format:"Janerachea_Febrerachea_Marsachea_Abrilachea_Maiachea_Junachea_Julaiachea_Agostachea_Setembrachea_Otubrachea_Novembrachea_Dezembrachea".split("_"),isFormat:/MMMM(\s)+D[oD]?/},monthsShort:"Jan._Feb._Mars_Abr._Mai_Jun_Jul._Ago._Set._Otu._Nov._Dez.".split("_"),monthsParseExact:true,weekdays:"Aitar_Somar_Mongllar_Budhvar_Birestar_Sukrar_Son'var".split("_"),weekdaysShort:"Ait._Som._Mon._Bud._Bre._Suk._Son.".split("_"),weekdaysMin:"Ai_Sm_Mo_Bu_Br_Su_Sn".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"A h:mm [vazta]",LTS:"A h:mm:ss [vazta]",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY A h:mm [vazta]",LLLL:"dddd, MMMM Do, YYYY, A h:mm [vazta]",llll:"ddd, D MMM YYYY, A h:mm [vazta]"},calendar:{sameDay:"[Aiz] LT",nextDay:"[Faleam] LT",nextWeek:"[Fuddlo] dddd[,] LT",lastDay:"[Kal] LT",lastWeek:"[Fattlo] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%s",past:"%s adim",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}(er)/,ordinal:function(e,t){switch(t){case"D":return e+"er";default:case"M":case"Q":case"DDD":case"d":case"w":case"W":return e}},week:{dow:0,doy:3},meridiemParse:/rati|sokallim|donparam|sanje/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="rati")return e<4?e:e+12;else if(t==="sokallim")return e;else if(t==="donparam")return e>12?e:e+12;else if(t==="sanje")return e+12},meridiem:function(e,t,n){if(e<4)return"rati";else if(e<12)return"sokallim";else if(e<16)return"donparam";else if(e<20)return"sanje";else return"rati"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"૧",2:"૨",3:"૩",4:"૪",5:"૫",6:"૬",7:"૭",8:"૮",9:"૯",0:"૦"},n={"૧":"1","૨":"2","૩":"3","૪":"4","૫":"5","૬":"6","૭":"7","૮":"8","૯":"9","૦":"0"},a;e.defineLocale("gu",{months:"જાન્યુઆરી_ફેબ્રુઆરી_માર્ચ_એપ્રિલ_મે_જૂન_જુલાઈ_ઑગસ્ટ_સપ્ટેમ્બર_ઑક્ટ્બર_નવેમ્બર_ડિસેમ્બર".split("_"),monthsShort:"જાન્યુ._ફેબ્રુ._માર્ચ_એપ્રિ._મે_જૂન_જુલા._ઑગ._સપ્ટે._ઑક્ટ્._નવે._ડિસે.".split("_"),monthsParseExact:true,weekdays:"રવિવાર_સોમવાર_મંગળવાર_બુધ્વાર_ગુરુવાર_શુક્રવાર_શનિવાર".split("_"),weekdaysShort:"રવિ_સોમ_મંગળ_બુધ્_ગુરુ_શુક્ર_શનિ".split("_"),weekdaysMin:"ર_સો_મં_બુ_ગુ_શુ_શ".split("_"),longDateFormat:{LT:"A h:mm વાગ્યે",LTS:"A h:mm:ss વાગ્યે",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm વાગ્યે",LLLL:"dddd, D MMMM YYYY, A h:mm વાગ્યે"},calendar:{sameDay:"[આજ] LT",nextDay:"[કાલે] LT",nextWeek:"dddd, LT",lastDay:"[ગઇકાલે] LT",lastWeek:"[પાછલા] dddd, LT",sameElse:"L"},relativeTime:{future:"%s મા",past:"%s પહેલા",s:"અમુક પળો",ss:"%d સેકંડ",m:"એક મિનિટ",mm:"%d મિનિટ",h:"એક કલાક",hh:"%d કલાક",d:"એક દિવસ",dd:"%d દિવસ",M:"એક મહિનો",MM:"%d મહિનો",y:"એક વર્ષ",yy:"%d વર્ષ"},preparse:function(e){return e.replace(/[૧૨૩૪૫૬૭૮૯૦]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/રાત|બપોર|સવાર|સાંજ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="રાત")return e<4?e:e+12;else if(t==="સવાર")return e;else if(t==="બપોર")return e>=10?e:e+12;else if(t==="સાંજ")return e+12},meridiem:function(e,t,n){if(e<4)return"રાત";else if(e<10)return"સવાર";else if(e<17)return"બપોર";else if(e<20)return"સાંજ";else return"રાત"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("he",{months:"ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר".split("_"),monthsShort:"ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳".split("_"),weekdays:"ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת".split("_"),weekdaysShort:"א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳".split("_"),weekdaysMin:"א_ב_ג_ד_ה_ו_ש".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [ב]MMMM YYYY",LLL:"D [ב]MMMM YYYY HH:mm",LLLL:"dddd, D [ב]MMMM YYYY HH:mm",l:"D/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[היום ב־]LT",nextDay:"[מחר ב־]LT",nextWeek:"dddd [בשעה] LT",lastDay:"[אתמול ב־]LT",lastWeek:"[ביום] dddd [האחרון בשעה] LT",sameElse:"L"},relativeTime:{future:"בעוד %s",past:"לפני %s",s:"מספר שניות",ss:"%d שניות",m:"דקה",mm:"%d דקות",h:"שעה",hh:function(e){if(e===2)return"שעתיים";return e+" שעות"},d:"יום",dd:function(e){if(e===2)return"יומיים";return e+" ימים"},M:"חודש",MM:function(e){if(e===2)return"חודשיים";return e+" חודשים"},y:"שנה",yy:function(e){if(e===2)return"שנתיים";else if(e%10===0&&e!==10)return e+" שנה";return e+" שנים"}},meridiemParse:/אחה"צ|לפנה"צ|אחרי הצהריים|לפני הצהריים|לפנות בוקר|בבוקר|בערב/i,isPM:function(e){return/^(אחה"צ|אחרי הצהריים|בערב)$/.test(e)},meridiem:function(e,t,n){if(e<5)return"לפנות בוקר";else if(e<10)return"בבוקר";else if(e<12)return n?'לפנה"צ':"לפני הצהריים";else if(e<18)return n?'אחה"צ':"אחרי הצהריים";else return"בערב"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},n={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},a=[/^जन/i,/^फ़र|फर/i,/^मार्च/i,/^अप्रै/i,/^मई/i,/^जून/i,/^जुल/i,/^अग/i,/^सितं|सित/i,/^अक्टू/i,/^नव|नवं/i,/^दिसं|दिस/i],r=[/^जन/i,/^फ़र/i,/^मार्च/i,/^अप्रै/i,/^मई/i,/^जून/i,/^जुल/i,/^अग/i,/^सित/i,/^अक्टू/i,/^नव/i,/^दिस/i],o;e.defineLocale("hi",{months:{format:"जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर".split("_"),standalone:"जनवरी_फरवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितंबर_अक्टूबर_नवंबर_दिसंबर".split("_")},monthsShort:"जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.".split("_"),weekdays:"रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm बजे",LTS:"A h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm बजे",LLLL:"dddd, D MMMM YYYY, A h:mm बजे"},monthsParse:a,longMonthsParse:a,shortMonthsParse:r,monthsRegex:/^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,monthsShortRegex:/^(जनवरी|जन\.?|फ़रवरी|फरवरी|फ़र\.?|मार्च?|अप्रैल|अप्रै\.?|मई?|जून?|जुलाई|जुल\.?|अगस्त|अग\.?|सितम्बर|सितंबर|सित\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर|नव\.?|दिसम्बर|दिसंबर|दिस\.?)/i,monthsStrictRegex:/^(जनवरी?|फ़रवरी|फरवरी?|मार्च?|अप्रैल?|मई?|जून?|जुलाई?|अगस्त?|सितम्बर|सितंबर|सित?\.?|अक्टूबर|अक्टू\.?|नवम्बर|नवंबर?|दिसम्बर|दिसंबर?)/i,monthsShortStrictRegex:/^(जन\.?|फ़र\.?|मार्च?|अप्रै\.?|मई?|जून?|जुल\.?|अग\.?|सित\.?|अक्टू\.?|नव\.?|दिस\.?)/i,calendar:{sameDay:"[आज] LT",nextDay:"[कल] LT",nextWeek:"dddd, LT",lastDay:"[कल] LT",lastWeek:"[पिछले] dddd, LT",sameElse:"L"},relativeTime:{future:"%s में",past:"%s पहले",s:"कुछ ही क्षण",ss:"%d सेकंड",m:"एक मिनट",mm:"%d मिनट",h:"एक घंटा",hh:"%d घंटे",d:"एक दिन",dd:"%d दिन",M:"एक महीने",MM:"%d महीने",y:"एक वर्ष",yy:"%d वर्ष"},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/रात|सुबह|दोपहर|शाम/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="रात")return e<4?e:e+12;else if(t==="सुबह")return e;else if(t==="दोपहर")return e>=10?e:e+12;else if(t==="शाम")return e+12},meridiem:function(e,t,n){if(e<4)return"रात";else if(e<10)return"सुबह";else if(e<17)return"दोपहर";else if(e<20)return"शाम";else return"रात"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n){var a=e+" ";switch(n){case"ss":if(e===1)a+="sekunda";else if(e===2||e===3||e===4)a+="sekunde";else a+="sekundi";return a;case"m":return t?"jedna minuta":"jedne minute";case"mm":if(e===1)a+="minuta";else if(e===2||e===3||e===4)a+="minute";else a+="minuta";return a;case"h":return t?"jedan sat":"jednog sata";case"hh":if(e===1)a+="sat";else if(e===2||e===3||e===4)a+="sata";else a+="sati";return a;case"dd":if(e===1)a+="dan";else a+="dana";return a;case"MM":if(e===1)a+="mjesec";else if(e===2||e===3||e===4)a+="mjeseca";else a+="mjeseci";return a;case"yy":if(e===1)a+="godina";else if(e===2||e===3||e===4)a+="godine";else a+="godina";return a}}var n;e.defineLocale("hr",{months:{format:"siječnja_veljače_ožujka_travnja_svibnja_lipnja_srpnja_kolovoza_rujna_listopada_studenoga_prosinca".split("_"),standalone:"siječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac".split("_")},monthsShort:"sij._velj._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.".split("_"),monthsParseExact:true,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"Do MMMM YYYY",LLL:"Do MMMM YYYY H:mm",LLLL:"dddd, Do MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[jučer u] LT",lastWeek:function(){switch(this.day()){case 0:return"[prošlu] [nedjelju] [u] LT";case 3:return"[prošlu] [srijedu] [u] LT";case 6:return"[prošle] [subote] [u] LT";case 1:case 2:case 4:case 5:return"[prošli] dddd [u] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"par sekundi",ss:t,m:t,mm:t,h:t,hh:t,d:"dan",dd:t,M:"mjesec",MM:t,y:"godinu",yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t="vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton".split(" "),n;function a(e,t,n,a){var r=e;switch(n){case"s":return a||t?"néhány másodperc":"néhány másodperce";case"ss":return r+(a||t)?" másodperc":" másodperce";case"m":return"egy"+(a||t?" perc":" perce");case"mm":return r+(a||t?" perc":" perce");case"h":return"egy"+(a||t?" óra":" órája");case"hh":return r+(a||t?" óra":" órája");case"d":return"egy"+(a||t?" nap":" napja");case"dd":return r+(a||t?" nap":" napja");case"M":return"egy"+(a||t?" hónap":" hónapja");case"MM":return r+(a||t?" hónap":" hónapja");case"y":return"egy"+(a||t?" év":" éve");case"yy":return r+(a||t?" év":" éve")}return""}function r(e){return(e?"":"[múlt] ")+"["+t[this.day()]+"] LT[-kor]"}e.defineLocale("hu",{months:"január_február_március_április_május_június_július_augusztus_szeptember_október_november_december".split("_"),monthsShort:"jan._feb._márc._ápr._máj._jún._júl._aug._szept._okt._nov._dec.".split("_"),monthsParseExact:true,weekdays:"vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat".split("_"),weekdaysShort:"vas_hét_kedd_sze_csüt_pén_szo".split("_"),weekdaysMin:"v_h_k_sze_cs_p_szo".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY. MMMM D.",LLL:"YYYY. MMMM D. H:mm",LLLL:"YYYY. MMMM D., dddd H:mm"},meridiemParse:/de|du/i,isPM:function(e){return e.charAt(1).toLowerCase()==="u"},meridiem:function(e,t,n){if(e<12)return n===true?"de":"DE";else return n===true?"du":"DU"},calendar:{sameDay:"[ma] LT[-kor]",nextDay:"[holnap] LT[-kor]",nextWeek:function(){return r.call(this,true)},lastDay:"[tegnap] LT[-kor]",lastWeek:function(){return r.call(this,false)},sameElse:"L"},relativeTime:{future:"%s múlva",past:"%s",s:a,ss:a,m:a,mm:a,h:a,hh:a,d:a,dd:a,M:a,MM:a,y:a,yy:a},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("hy-am",{months:{format:"հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի".split("_"),standalone:"հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր".split("_")},monthsShort:"հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ".split("_"),weekdays:"կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ".split("_"),weekdaysShort:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),weekdaysMin:"կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY թ.",LLL:"D MMMM YYYY թ., HH:mm",LLLL:"dddd, D MMMM YYYY թ., HH:mm"},calendar:{sameDay:"[այսօր] LT",nextDay:"[վաղը] LT",lastDay:"[երեկ] LT",nextWeek:function(){return"dddd [օրը ժամը] LT"},lastWeek:function(){return"[անցած] dddd [օրը ժամը] LT"},sameElse:"L"},relativeTime:{future:"%s հետո",past:"%s առաջ",s:"մի քանի վայրկյան",ss:"%d վայրկյան",m:"րոպե",mm:"%d րոպե",h:"ժամ",hh:"%d ժամ",d:"օր",dd:"%d օր",M:"ամիս",MM:"%d ամիս",y:"տարի",yy:"%d տարի"},meridiemParse:/գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,isPM:function(e){return/^(ցերեկվա|երեկոյան)$/.test(e)},meridiem:function(e){if(e<4)return"գիշերվա";else if(e<12)return"առավոտվա";else if(e<17)return"ցերեկվա";else return"երեկոյան"},dayOfMonthOrdinalParse:/\d{1,2}|\d{1,2}-(ին|րդ)/,ordinal:function(e,t){switch(t){case"DDD":case"w":case"W":case"DDDo":if(e===1)return e+"-ին";return e+"-րդ";default:return e}},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("id",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Agt_Sep_Okt_Nov_Des".split("_"),weekdays:"Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu".split("_"),weekdaysShort:"Min_Sen_Sel_Rab_Kam_Jum_Sab".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|siang|sore|malam/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="pagi")return e;else if(t==="siang")return e>=11?e:e+12;else if(t==="sore"||t==="malam")return e+12},meridiem:function(e,t,n){if(e<11)return"pagi";else if(e<15)return"siang";else if(e<19)return"sore";else return"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Besok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kemarin pukul] LT",lastWeek:"dddd [lalu pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lalu",s:"beberapa detik",ss:"%d detik",m:"semenit",mm:"%d menit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function o(e){if(e%100===11)return true;else if(e%10===1)return false;return true}function t(e,t,n,a){var r=e+" ";switch(n){case"s":return t||a?"nokkrar sekúndur":"nokkrum sekúndum";case"ss":if(o(e))return r+(t||a?"sekúndur":"sekúndum");return r+"sekúnda";case"m":return t?"mínúta":"mínútu";case"mm":if(o(e))return r+(t||a?"mínútur":"mínútum");else if(t)return r+"mínúta";return r+"mínútu";case"hh":if(o(e))return r+(t||a?"klukkustundir":"klukkustundum");return r+"klukkustund";case"d":if(t)return"dagur";return a?"dag":"degi";case"dd":if(o(e)){if(t)return r+"dagar";return r+(a?"daga":"dögum")}else if(t)return r+"dagur";return r+(a?"dag":"degi");case"M":if(t)return"mánuður";return a?"mánuð":"mánuði";case"MM":if(o(e)){if(t)return r+"mánuðir";return r+(a?"mánuði":"mánuðum")}else if(t)return r+"mánuður";return r+(a?"mánuð":"mánuði");case"y":return t||a?"ár":"ári";case"yy":if(o(e))return r+(t||a?"ár":"árum");return r+(t||a?"ár":"ári")}}var n;e.defineLocale("is",{months:"janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember".split("_"),monthsShort:"jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des".split("_"),weekdays:"sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur".split("_"),weekdaysShort:"sun_mán_þri_mið_fim_fös_lau".split("_"),weekdaysMin:"Su_Má_Þr_Mi_Fi_Fö_La".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd, D. MMMM YYYY [kl.] H:mm"},calendar:{sameDay:"[í dag kl.] LT",nextDay:"[á morgun kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[í gær kl.] LT",lastWeek:"[síðasta] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"eftir %s",past:"fyrir %s síðan",s:t,ss:t,m:t,mm:t,h:"klukkustund",hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("it",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:function(){return"[Oggi a"+(this.hours()>1?"lle ":this.hours()===0?" ":"ll'")+"]LT"},nextDay:function(){return"[Domani a"+(this.hours()>1?"lle ":this.hours()===0?" ":"ll'")+"]LT"},nextWeek:function(){return"dddd [a"+(this.hours()>1?"lle ":this.hours()===0?" ":"ll'")+"]LT"},lastDay:function(){return"[Ieri a"+(this.hours()>1?"lle ":this.hours()===0?" ":"ll'")+"]LT"},lastWeek:function(){switch(this.day()){case 0:return"[La scorsa] dddd [a"+(this.hours()>1?"lle ":this.hours()===0?" ":"ll'")+"]LT";default:return"[Lo scorso] dddd [a"+(this.hours()>1?"lle ":this.hours()===0?" ":"ll'")+"]LT"}},sameElse:"L"},relativeTime:{future:"tra %s",past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",w:"una settimana",ww:"%d settimane",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("it-ch",{months:"gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre".split("_"),monthsShort:"gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic".split("_"),weekdays:"domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato".split("_"),weekdaysShort:"dom_lun_mar_mer_gio_ven_sab".split("_"),weekdaysMin:"do_lu_ma_me_gi_ve_sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[Oggi alle] LT",nextDay:"[Domani alle] LT",nextWeek:"dddd [alle] LT",lastDay:"[Ieri alle] LT",lastWeek:function(){switch(this.day()){case 0:return"[la scorsa] dddd [alle] LT";default:return"[lo scorso] dddd [alle] LT"}},sameElse:"L"},relativeTime:{future:function(e){return(/^[0-9].+$/.test(e)?"tra":"in")+" "+e},past:"%s fa",s:"alcuni secondi",ss:"%d secondi",m:"un minuto",mm:"%d minuti",h:"un'ora",hh:"%d ore",d:"un giorno",dd:"%d giorni",M:"un mese",MM:"%d mesi",y:"un anno",yy:"%d anni"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ja",{eras:[{since:"2019-05-01",offset:1,name:"令和",narrow:"㋿",abbr:"R"},{since:"1989-01-08",until:"2019-04-30",offset:1,name:"平成",narrow:"㍻",abbr:"H"},{since:"1926-12-25",until:"1989-01-07",offset:1,name:"昭和",narrow:"㍼",abbr:"S"},{since:"1912-07-30",until:"1926-12-24",offset:1,name:"大正",narrow:"㍽",abbr:"T"},{since:"1873-01-01",until:"1912-07-29",offset:6,name:"明治",narrow:"㍾",abbr:"M"},{since:"0001-01-01",until:"1873-12-31",offset:1,name:"西暦",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-Infinity,offset:1,name:"紀元前",narrow:"BC",abbr:"BC"}],eraYearOrdinalRegex:/(元|\d+)年/,eraYearOrdinalParse:function(e,t){return t[1]==="元"?1:parseInt(t[1]||e,10)},months:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日".split("_"),weekdaysShort:"日_月_火_水_木_金_土".split("_"),weekdaysMin:"日_月_火_水_木_金_土".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日 dddd HH:mm",l:"YYYY/MM/DD",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日(ddd) HH:mm"},meridiemParse:/午前|午後/i,isPM:function(e){return e==="午後"},meridiem:function(e,t,n){if(e<12)return"午前";else return"午後"},calendar:{sameDay:"[今日] LT",nextDay:"[明日] LT",nextWeek:function(e){if(e.week()!==this.week())return"[来週]dddd LT";else return"dddd LT"},lastDay:"[昨日] LT",lastWeek:function(e){if(this.week()!==e.week())return"[先週]dddd LT";else return"dddd LT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}日/,ordinal:function(e,t){switch(t){case"y":return e===1?"元年":e+"年";case"d":case"D":case"DDD":return e+"日";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"数秒",ss:"%d秒",m:"1分",mm:"%d分",h:"1時間",hh:"%d時間",d:"1日",dd:"%d日",M:"1ヶ月",MM:"%dヶ月",y:"1年",yy:"%d年"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("jv",{months:"Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_Nopember_Desember".split("_"),monthsShort:"Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nop_Des".split("_"),weekdays:"Minggu_Senen_Seloso_Rebu_Kemis_Jemuwah_Septu".split("_"),weekdaysShort:"Min_Sen_Sel_Reb_Kem_Jem_Sep".split("_"),weekdaysMin:"Mg_Sn_Sl_Rb_Km_Jm_Sp".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/enjing|siyang|sonten|ndalu/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="enjing")return e;else if(t==="siyang")return e>=11?e:e+12;else if(t==="sonten"||t==="ndalu")return e+12},meridiem:function(e,t,n){if(e<11)return"enjing";else if(e<15)return"siyang";else if(e<19)return"sonten";else return"ndalu"},calendar:{sameDay:"[Dinten puniko pukul] LT",nextDay:"[Mbenjang pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kala wingi pukul] LT",lastWeek:"dddd [kepengker pukul] LT",sameElse:"L"},relativeTime:{future:"wonten ing %s",past:"%s ingkang kepengker",s:"sawetawis detik",ss:"%d detik",m:"setunggal menit",mm:"%d menit",h:"setunggal jam",hh:"%d jam",d:"sedinten",dd:"%d dinten",M:"sewulan",MM:"%d wulan",y:"setaun",yy:"%d taun"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ka",{months:"იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი".split("_"),monthsShort:"იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ".split("_"),weekdays:{standalone:"კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი".split("_"),format:"კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს".split("_"),isFormat:/(წინა|შემდეგ)/},weekdaysShort:"კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ".split("_"),weekdaysMin:"კვ_ორ_სა_ოთ_ხუ_პა_შა".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[დღეს] LT[-ზე]",nextDay:"[ხვალ] LT[-ზე]",lastDay:"[გუშინ] LT[-ზე]",nextWeek:"[შემდეგ] dddd LT[-ზე]",lastWeek:"[წინა] dddd LT-ზე",sameElse:"L"},relativeTime:{future:function(e){return e.replace(/(წამ|წუთ|საათ|წელ|დღ|თვ)(ი|ე)/,function(e,t,n){return n==="ი"?t+"ში":t+n+"ში"})},past:function(e){if(/(წამი|წუთი|საათი|დღე|თვე)/.test(e))return e.replace(/(ი|ე)$/,"ის წინ");if(/წელი/.test(e))return e.replace(/წელი$/,"წლის წინ");return e},s:"რამდენიმე წამი",ss:"%d წამი",m:"წუთი",mm:"%d წუთი",h:"საათი",hh:"%d საათი",d:"დღე",dd:"%d დღე",M:"თვე",MM:"%d თვე",y:"წელი",yy:"%d წელი"},dayOfMonthOrdinalParse:/0|1-ლი|მე-\d{1,2}|\d{1,2}-ე/,ordinal:function(e){if(e===0)return e;if(e===1)return e+"-ლი";if(e<20||e<=100&&e%20===0||e%100===0)return"მე-"+e;return e+"-ე"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var a={0:"-ші",1:"-ші",2:"-ші",3:"-ші",4:"-ші",5:"-ші",6:"-шы",7:"-ші",8:"-ші",9:"-шы",10:"-шы",20:"-шы",30:"-шы",40:"-шы",50:"-ші",60:"-шы",70:"-ші",80:"-ші",90:"-шы",100:"-ші"},t;e.defineLocale("kk",{months:"қаңтар_ақпан_наурыз_сәуір_мамыр_маусым_шілде_тамыз_қыркүйек_қазан_қараша_желтоқсан".split("_"),monthsShort:"қаң_ақп_нау_сәу_мам_мау_шіл_там_қыр_қаз_қар_жел".split("_"),weekdays:"жексенбі_дүйсенбі_сейсенбі_сәрсенбі_бейсенбі_жұма_сенбі".split("_"),weekdaysShort:"жек_дүй_сей_сәр_бей_жұм_сен".split("_"),weekdaysMin:"жк_дй_сй_ср_бй_жм_сн".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Бүгін сағат] LT",nextDay:"[Ертең сағат] LT",nextWeek:"dddd [сағат] LT",lastDay:"[Кеше сағат] LT",lastWeek:"[Өткен аптаның] dddd [сағат] LT",sameElse:"L"},relativeTime:{future:"%s ішінде",past:"%s бұрын",s:"бірнеше секунд",ss:"%d секунд",m:"бір минут",mm:"%d минут",h:"бір сағат",hh:"%d сағат",d:"бір күн",dd:"%d күн",M:"бір ай",MM:"%d ай",y:"бір жыл",yy:"%d жыл"},dayOfMonthOrdinalParse:/\d{1,2}-(ші|шы)/,ordinal:function(e){var t=e%10,n=e>=100?100:null;return e+(a[e]||a[t]||a[n])},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"១",2:"២",3:"៣",4:"៤",5:"៥",6:"៦",7:"៧",8:"៨",9:"៩",0:"០"},n={"១":"1","២":"2","៣":"3","៤":"4","៥":"5","៦":"6","៧":"7","៨":"8","៩":"9","០":"0"},a;e.defineLocale("km",{months:"មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),monthsShort:"មករា_កុម្ភៈ_មីនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ".split("_"),weekdays:"អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍".split("_"),weekdaysShort:"អា_ច_អ_ព_ព្រ_សុ_ស".split("_"),weekdaysMin:"អា_ច_អ_ព_ព្រ_សុ_ស".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/ព្រឹក|ល្ងាច/,isPM:function(e){return e==="ល្ងាច"},meridiem:function(e,t,n){if(e<12)return"ព្រឹក";else return"ល្ងាច"},calendar:{sameDay:"[ថ្ងៃនេះ ម៉ោង] LT",nextDay:"[ស្អែក ម៉ោង] LT",nextWeek:"dddd [ម៉ោង] LT",lastDay:"[ម្សិលមិញ ម៉ោង] LT",lastWeek:"dddd [សប្តាហ៍មុន] [ម៉ោង] LT",sameElse:"L"},relativeTime:{future:"%sទៀត",past:"%sមុន",s:"ប៉ុន្មានវិនាទី",ss:"%d វិនាទី",m:"មួយនាទី",mm:"%d នាទី",h:"មួយម៉ោង",hh:"%d ម៉ោង",d:"មួយថ្ងៃ",dd:"%d ថ្ងៃ",M:"មួយខែ",MM:"%d ខែ",y:"មួយឆ្នាំ",yy:"%d ឆ្នាំ"},dayOfMonthOrdinalParse:/ទី\d{1,2}/,ordinal:"ទី%d",preparse:function(e){return e.replace(/[១២៣៤៥៦៧៨៩០]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"೧",2:"೨",3:"೩",4:"೪",5:"೫",6:"೬",7:"೭",8:"೮",9:"೯",0:"೦"},n={"೧":"1","೨":"2","೩":"3","೪":"4","೫":"5","೬":"6","೭":"7","೮":"8","೯":"9","೦":"0"},a;e.defineLocale("kn",{months:"ಜನವರಿ_ಫೆಬ್ರವರಿ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂಬರ್_ಅಕ್ಟೋಬರ್_ನವೆಂಬರ್_ಡಿಸೆಂಬರ್".split("_"),monthsShort:"ಜನ_ಫೆಬ್ರ_ಮಾರ್ಚ್_ಏಪ್ರಿಲ್_ಮೇ_ಜೂನ್_ಜುಲೈ_ಆಗಸ್ಟ್_ಸೆಪ್ಟೆಂ_ಅಕ್ಟೋ_ನವೆಂ_ಡಿಸೆಂ".split("_"),monthsParseExact:true,weekdays:"ಭಾನುವಾರ_ಸೋಮವಾರ_ಮಂಗಳವಾರ_ಬುಧವಾರ_ಗುರುವಾರ_ಶುಕ್ರವಾರ_ಶನಿವಾರ".split("_"),weekdaysShort:"ಭಾನು_ಸೋಮ_ಮಂಗಳ_ಬುಧ_ಗುರು_ಶುಕ್ರ_ಶನಿ".split("_"),weekdaysMin:"ಭಾ_ಸೋ_ಮಂ_ಬು_ಗು_ಶು_ಶ".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[ಇಂದು] LT",nextDay:"[ನಾಳೆ] LT",nextWeek:"dddd, LT",lastDay:"[ನಿನ್ನೆ] LT",lastWeek:"[ಕೊನೆಯ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ನಂತರ",past:"%s ಹಿಂದೆ",s:"ಕೆಲವು ಕ್ಷಣಗಳು",ss:"%d ಸೆಕೆಂಡುಗಳು",m:"ಒಂದು ನಿಮಿಷ",mm:"%d ನಿಮಿಷ",h:"ಒಂದು ಗಂಟೆ",hh:"%d ಗಂಟೆ",d:"ಒಂದು ದಿನ",dd:"%d ದಿನ",M:"ಒಂದು ತಿಂಗಳು",MM:"%d ತಿಂಗಳು",y:"ಒಂದು ವರ್ಷ",yy:"%d ವರ್ಷ"},preparse:function(e){return e.replace(/[೧೨೩೪೫೬೭೮೯೦]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/ರಾತ್ರಿ|ಬೆಳಿಗ್ಗೆ|ಮಧ್ಯಾಹ್ನ|ಸಂಜೆ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="ರಾತ್ರಿ")return e<4?e:e+12;else if(t==="ಬೆಳಿಗ್ಗೆ")return e;else if(t==="ಮಧ್ಯಾಹ್ನ")return e>=10?e:e+12;else if(t==="ಸಂಜೆ")return e+12},meridiem:function(e,t,n){if(e<4)return"ರಾತ್ರಿ";else if(e<10)return"ಬೆಳಿಗ್ಗೆ";else if(e<17)return"ಮಧ್ಯಾಹ್ನ";else if(e<20)return"ಸಂಜೆ";else return"ರಾತ್ರಿ"},dayOfMonthOrdinalParse:/\d{1,2}(ನೇ)/,ordinal:function(e){return e+"ನೇ"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ko",{months:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),monthsShort:"1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월".split("_"),weekdays:"일요일_월요일_화요일_수요일_목요일_금요일_토요일".split("_"),weekdaysShort:"일_월_화_수_목_금_토".split("_"),weekdaysMin:"일_월_화_수_목_금_토".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"YYYY.MM.DD.",LL:"YYYY년 MMMM D일",LLL:"YYYY년 MMMM D일 A h:mm",LLLL:"YYYY년 MMMM D일 dddd A h:mm",l:"YYYY.MM.DD.",ll:"YYYY년 MMMM D일",lll:"YYYY년 MMMM D일 A h:mm",llll:"YYYY년 MMMM D일 dddd A h:mm"},calendar:{sameDay:"오늘 LT",nextDay:"내일 LT",nextWeek:"dddd LT",lastDay:"어제 LT",lastWeek:"지난주 dddd LT",sameElse:"L"},relativeTime:{future:"%s 후",past:"%s 전",s:"몇 초",ss:"%d초",m:"1분",mm:"%d분",h:"한 시간",hh:"%d시간",d:"하루",dd:"%d일",M:"한 달",MM:"%d달",y:"일 년",yy:"%d년"},dayOfMonthOrdinalParse:/\d{1,2}(일|월|주)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"일";case"M":return e+"월";case"w":case"W":return e+"주";default:return e}},meridiemParse:/오전|오후/,isPM:function(e){return e==="오후"},meridiem:function(e,t,n){return e<12?"오전":"오후"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"١",2:"٢",3:"٣",4:"٤",5:"٥",6:"٦",7:"٧",8:"٨",9:"٩",0:"٠"},n={"١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","٠":"0"},a=["کانونی دووەم","شوبات","ئازار","نیسان","ئایار","حوزەیران","تەمموز","ئاب","ئەیلوول","تشرینی یەكەم","تشرینی دووەم","كانونی یەکەم"],r;e.defineLocale("ku",{months:a,monthsShort:a,weekdays:"یه‌كشه‌ممه‌_دووشه‌ممه‌_سێشه‌ممه‌_چوارشه‌ممه‌_پێنجشه‌ممه‌_هه‌ینی_شه‌ممه‌".split("_"),weekdaysShort:"یه‌كشه‌م_دووشه‌م_سێشه‌م_چوارشه‌م_پێنجشه‌م_هه‌ینی_شه‌ممه‌".split("_"),weekdaysMin:"ی_د_س_چ_پ_ه_ش".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},meridiemParse:/ئێواره‌|به‌یانی/,isPM:function(e){return/ئێواره‌/.test(e)},meridiem:function(e,t,n){if(e<12)return"به‌یانی";else return"ئێواره‌"},calendar:{sameDay:"[ئه‌مرۆ كاتژمێر] LT",nextDay:"[به‌یانی كاتژمێر] LT",nextWeek:"dddd [كاتژمێر] LT",lastDay:"[دوێنێ كاتژمێر] LT",lastWeek:"dddd [كاتژمێر] LT",sameElse:"L"},relativeTime:{future:"له‌ %s",past:"%s",s:"چه‌ند چركه‌یه‌ك",ss:"چركه‌ %d",m:"یه‌ك خوله‌ك",mm:"%d خوله‌ك",h:"یه‌ك كاتژمێر",hh:"%d كاتژمێر",d:"یه‌ك ڕۆژ",dd:"%d ڕۆژ",M:"یه‌ك مانگ",MM:"%d مانگ",y:"یه‌ك ساڵ",yy:"%d ساڵ"},preparse:function(e){return e.replace(/[١٢٣٤٥٦٧٨٩٠]/g,function(e){return n[e]}).replace(/،/g,",")},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]}).replace(/,/g,"،")},week:{dow:6,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var a={0:"-чү",1:"-чи",2:"-чи",3:"-чү",4:"-чү",5:"-чи",6:"-чы",7:"-чи",8:"-чи",9:"-чу",10:"-чу",20:"-чы",30:"-чу",40:"-чы",50:"-чү",60:"-чы",70:"-чи",80:"-чи",90:"-чу",100:"-чү"},t;e.defineLocale("ky",{months:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_"),monthsShort:"янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек".split("_"),weekdays:"Жекшемби_Дүйшөмбү_Шейшемби_Шаршемби_Бейшемби_Жума_Ишемби".split("_"),weekdaysShort:"Жек_Дүй_Шей_Шар_Бей_Жум_Ише".split("_"),weekdaysMin:"Жк_Дй_Шй_Шр_Бй_Жм_Иш".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Бүгүн саат] LT",nextDay:"[Эртең саат] LT",nextWeek:"dddd [саат] LT",lastDay:"[Кечээ саат] LT",lastWeek:"[Өткөн аптанын] dddd [күнү] [саат] LT",sameElse:"L"},relativeTime:{future:"%s ичинде",past:"%s мурун",s:"бирнече секунд",ss:"%d секунд",m:"бир мүнөт",mm:"%d мүнөт",h:"бир саат",hh:"%d саат",d:"бир күн",dd:"%d күн",M:"бир ай",MM:"%d ай",y:"бир жыл",yy:"%d жыл"},dayOfMonthOrdinalParse:/\d{1,2}-(чи|чы|чү|чу)/,ordinal:function(e){var t=e%10,n=e>=100?100:null;return e+(a[e]||a[t]||a[n])},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r={m:["eng Minutt","enger Minutt"],h:["eng Stonn","enger Stonn"],d:["een Dag","engem Dag"],M:["ee Mount","engem Mount"],y:["ee Joer","engem Joer"]};return t?r[n][0]:r[n][1]}function n(e){var t=e.substr(0,e.indexOf(" "));if(r(t))return"a "+e;return"an "+e}function a(e){var t=e.substr(0,e.indexOf(" "));if(r(t))return"viru "+e;return"virun "+e}function r(e){e=parseInt(e,10);if(isNaN(e))return false;if(e<0)return true;else if(e<10){if(4<=e&&e<=7)return true;return false}else if(e<100){var t=e%10,n=e/10;if(t===0)return r(n);return r(t)}else if(e<1e4){while(e>=10)e=e/10;return r(e)}else{e=e/1e3;return r(e)}}var o;e.defineLocale("lb",{months:"Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember".split("_"),monthsShort:"Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.".split("_"),monthsParseExact:true,weekdays:"Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg".split("_"),weekdaysShort:"So._Mé._Dë._Më._Do._Fr._Sa.".split("_"),weekdaysMin:"So_Mé_Dë_Më_Do_Fr_Sa".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm [Auer]",LTS:"H:mm:ss [Auer]",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm [Auer]",LLLL:"dddd, D. MMMM YYYY H:mm [Auer]"},calendar:{sameDay:"[Haut um] LT",sameElse:"L",nextDay:"[Muer um] LT",nextWeek:"dddd [um] LT",lastDay:"[Gëschter um] LT",lastWeek:function(){switch(this.day()){case 2:case 4:return"[Leschten] dddd [um] LT";default:return"[Leschte] dddd [um] LT"}}},relativeTime:{future:n,past:a,s:"e puer Sekonnen",ss:"%d Sekonnen",m:t,mm:"%d Minutten",h:t,hh:"%d Stonnen",d:t,dd:"%d Deeg",M:t,MM:"%d Méint",y:t,yy:"%d Joer"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("lo",{months:"ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ".split("_"),monthsShort:"ມັງກອນ_ກຸມພາ_ມີນາ_ເມສາ_ພຶດສະພາ_ມິຖຸນາ_ກໍລະກົດ_ສິງຫາ_ກັນຍາ_ຕຸລາ_ພະຈິກ_ທັນວາ".split("_"),weekdays:"ອາທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ".split("_"),weekdaysShort:"ທິດ_ຈັນ_ອັງຄານ_ພຸດ_ພະຫັດ_ສຸກ_ເສົາ".split("_"),weekdaysMin:"ທ_ຈ_ອຄ_ພ_ພຫ_ສກ_ສ".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"ວັນdddd D MMMM YYYY HH:mm"},meridiemParse:/ຕອນເຊົ້າ|ຕອນແລງ/,isPM:function(e){return e==="ຕອນແລງ"},meridiem:function(e,t,n){if(e<12)return"ຕອນເຊົ້າ";else return"ຕອນແລງ"},calendar:{sameDay:"[ມື້ນີ້ເວລາ] LT",nextDay:"[ມື້ອື່ນເວລາ] LT",nextWeek:"[ວັນ]dddd[ໜ້າເວລາ] LT",lastDay:"[ມື້ວານນີ້ເວລາ] LT",lastWeek:"[ວັນ]dddd[ແລ້ວນີ້ເວລາ] LT",sameElse:"L"},relativeTime:{future:"ອີກ %s",past:"%sຜ່ານມາ",s:"ບໍ່ເທົ່າໃດວິນາທີ",ss:"%d ວິນາທີ",m:"1 ນາທີ",mm:"%d ນາທີ",h:"1 ຊົ່ວໂມງ",hh:"%d ຊົ່ວໂມງ",d:"1 ມື້",dd:"%d ມື້",M:"1 ເດືອນ",MM:"%d ເດືອນ",y:"1 ປີ",yy:"%d ປີ"},dayOfMonthOrdinalParse:/(ທີ່)\d{1,2}/,ordinal:function(e){return"ທີ່"+e}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={ss:"sekundė_sekundžių_sekundes",m:"minutė_minutės_minutę",mm:"minutės_minučių_minutes",h:"valanda_valandos_valandą",hh:"valandos_valandų_valandas",d:"diena_dienos_dieną",dd:"dienos_dienų_dienas",M:"mėnuo_mėnesio_mėnesį",MM:"mėnesiai_mėnesių_mėnesius",y:"metai_metų_metus",yy:"metai_metų_metus"},n;function a(e,t,n,a){if(t)return"kelios sekundės";else return a?"kelių sekundžių":"kelias sekundes"}function o(e,t,n,a){return t?s(n)[0]:a?s(n)[1]:s(n)[2]}function i(e){return e%10===0||e>10&&e<20}function s(e){return t[e].split("_")}function r(e,t,n,a){var r=e+" ";if(e===1)return r+o(e,t,n[0],a);else if(t)return r+(i(e)?s(n)[1]:s(n)[0]);else if(a)return r+s(n)[1];else return r+(i(e)?s(n)[1]:s(n)[2])}e.defineLocale("lt",{months:{format:"sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio".split("_"),standalone:"sausis_vasaris_kovas_balandis_gegužė_birželis_liepa_rugpjūtis_rugsėjis_spalis_lapkritis_gruodis".split("_"),isFormat:/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?|MMMM?(\[[^\[\]]*\]|\s)+D[oD]?/},monthsShort:"sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd".split("_"),weekdays:{format:"sekmadienį_pirmadienį_antradienį_trečiadienį_ketvirtadienį_penktadienį_šeštadienį".split("_"),standalone:"sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis".split("_"),isFormat:/dddd HH:mm/},weekdaysShort:"Sek_Pir_Ant_Tre_Ket_Pen_Šeš".split("_"),weekdaysMin:"S_P_A_T_K_Pn_Š".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY [m.] MMMM D [d.]",LLL:"YYYY [m.] MMMM D [d.], HH:mm [val.]",LLLL:"YYYY [m.] MMMM D [d.], dddd, HH:mm [val.]",l:"YYYY-MM-DD",ll:"YYYY [m.] MMMM D [d.]",lll:"YYYY [m.] MMMM D [d.], HH:mm [val.]",llll:"YYYY [m.] MMMM D [d.], ddd, HH:mm [val.]"},calendar:{sameDay:"[Šiandien] LT",nextDay:"[Rytoj] LT",nextWeek:"dddd LT",lastDay:"[Vakar] LT",lastWeek:"[Praėjusį] dddd LT",sameElse:"L"},relativeTime:{future:"po %s",past:"prieš %s",s:a,ss:r,m:o,mm:r,h:o,hh:r,d:o,dd:r,M:o,MM:r,y:o,yy:r},dayOfMonthOrdinalParse:/\d{1,2}-oji/,ordinal:function(e){return e+"-oji"},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var a={ss:"sekundes_sekundēm_sekunde_sekundes".split("_"),m:"minūtes_minūtēm_minūte_minūtes".split("_"),mm:"minūtes_minūtēm_minūte_minūtes".split("_"),h:"stundas_stundām_stunda_stundas".split("_"),hh:"stundas_stundām_stunda_stundas".split("_"),d:"dienas_dienām_diena_dienas".split("_"),dd:"dienas_dienām_diena_dienas".split("_"),M:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),MM:"mēneša_mēnešiem_mēnesis_mēneši".split("_"),y:"gada_gadiem_gads_gadi".split("_"),yy:"gada_gadiem_gads_gadi".split("_")},t;function r(e,t,n){if(n)return t%10===1&&t%100!==11?e[2]:e[3];else return t%10===1&&t%100!==11?e[0]:e[1]}function n(e,t,n){return e+" "+r(a[n],e,t)}function o(e,t,n){return r(a[n],e,t)}function i(e,t){return t?"dažas sekundes":"dažām sekundēm"}e.defineLocale("lv",{months:"janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris".split("_"),monthsShort:"jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec".split("_"),weekdays:"svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena".split("_"),weekdaysShort:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysMin:"Sv_P_O_T_C_Pk_S".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY.",LL:"YYYY. [gada] D. MMMM",LLL:"YYYY. [gada] D. MMMM, HH:mm",LLLL:"YYYY. [gada] D. MMMM, dddd, HH:mm"},calendar:{sameDay:"[Šodien pulksten] LT",nextDay:"[Rīt pulksten] LT",nextWeek:"dddd [pulksten] LT",lastDay:"[Vakar pulksten] LT",lastWeek:"[Pagājušā] dddd [pulksten] LT",sameElse:"L"},relativeTime:{future:"pēc %s",past:"pirms %s",s:i,ss:n,m:o,mm:n,h:o,hh:n,d:o,dd:n,M:o,MM:n,y:o,yy:n},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var r={words:{ss:["sekund","sekunda","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],dd:["dan","dana","dana"],MM:["mjesec","mjeseca","mjeseci"],yy:["godina","godine","godina"]},correctGrammaticalCase:function(e,t){return e===1?t[0]:e>=2&&e<=4?t[1]:t[2]},translate:function(e,t,n){var a=r.words[n];if(n.length===1)return t?a[0]:a[1];else return e+" "+r.correctGrammaticalCase(e,a)}},t;e.defineLocale("me",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:true,weekdays:"nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sri._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sjutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedjelju] [u] LT";case 3:return"[u] [srijedu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var e=["[prošle] [nedjelje] [u] LT","[prošlog] [ponedjeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srijede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return e[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"prije %s",s:"nekoliko sekundi",ss:r.translate,m:r.translate,mm:r.translate,h:r.translate,hh:r.translate,d:"dan",dd:r.translate,M:"mjesec",MM:r.translate,y:"godinu",yy:r.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("mi",{months:"Kohi-tāte_Hui-tanguru_Poutū-te-rangi_Paenga-whāwhā_Haratua_Pipiri_Hōngoingoi_Here-turi-kōkā_Mahuru_Whiringa-ā-nuku_Whiringa-ā-rangi_Hakihea".split("_"),monthsShort:"Kohi_Hui_Pou_Pae_Hara_Pipi_Hōngoi_Here_Mahu_Whi-nu_Whi-ra_Haki".split("_"),monthsRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,3}/i,monthsShortStrictRegex:/(?:['a-z\u0101\u014D\u016B]+\-?){1,2}/i,weekdays:"Rātapu_Mane_Tūrei_Wenerei_Tāite_Paraire_Hātarei".split("_"),weekdaysShort:"Ta_Ma_Tū_We_Tāi_Pa_Hā".split("_"),weekdaysMin:"Ta_Ma_Tū_We_Tāi_Pa_Hā".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [i] HH:mm",LLLL:"dddd, D MMMM YYYY [i] HH:mm"},calendar:{sameDay:"[i teie mahana, i] LT",nextDay:"[apopo i] LT",nextWeek:"dddd [i] LT",lastDay:"[inanahi i] LT",lastWeek:"dddd [whakamutunga i] LT",sameElse:"L"},relativeTime:{future:"i roto i %s",past:"%s i mua",s:"te hēkona ruarua",ss:"%d hēkona",m:"he meneti",mm:"%d meneti",h:"te haora",hh:"%d haora",d:"he ra",dd:"%d ra",M:"he marama",MM:"%d marama",y:"he tau",yy:"%d tau"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("mk",{months:"јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември".split("_"),monthsShort:"јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек".split("_"),weekdays:"недела_понеделник_вторник_среда_четврток_петок_сабота".split("_"),weekdaysShort:"нед_пон_вто_сре_чет_пет_саб".split("_"),weekdaysMin:"нe_пo_вт_ср_че_пе_сa".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[Денес во] LT",nextDay:"[Утре во] LT",nextWeek:"[Во] dddd [во] LT",lastDay:"[Вчера во] LT",lastWeek:function(){switch(this.day()){case 0:case 3:case 6:return"[Изминатата] dddd [во] LT";case 1:case 2:case 4:case 5:return"[Изминатиот] dddd [во] LT"}},sameElse:"L"},relativeTime:{future:"за %s",past:"пред %s",s:"неколку секунди",ss:"%d секунди",m:"една минута",mm:"%d минути",h:"еден час",hh:"%d часа",d:"еден ден",dd:"%d дена",M:"еден месец",MM:"%d месеци",y:"една година",yy:"%d години"},dayOfMonthOrdinalParse:/\d{1,2}-(ев|ен|ти|ви|ри|ми)/,ordinal:function(e){var t=e%10,n=e%100;if(e===0)return e+"-ев";else if(n===0)return e+"-ен";else if(n>10&&n<20)return e+"-ти";else if(t===1)return e+"-ви";else if(t===2)return e+"-ри";else if(t===7||t===8)return e+"-ми";else return e+"-ти"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ml",{months:"ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ".split("_"),monthsShort:"ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.".split("_"),monthsParseExact:true,weekdays:"ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച".split("_"),weekdaysShort:"ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി".split("_"),weekdaysMin:"ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ".split("_"),longDateFormat:{LT:"A h:mm -നു",LTS:"A h:mm:ss -നു",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm -നു",LLLL:"dddd, D MMMM YYYY, A h:mm -നു"},calendar:{sameDay:"[ഇന്ന്] LT",nextDay:"[നാളെ] LT",nextWeek:"dddd, LT",lastDay:"[ഇന്നലെ] LT",lastWeek:"[കഴിഞ്ഞ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s കഴിഞ്ഞ്",past:"%s മുൻപ്",s:"അൽപ നിമിഷങ്ങൾ",ss:"%d സെക്കൻഡ്",m:"ഒരു മിനിറ്റ്",mm:"%d മിനിറ്റ്",h:"ഒരു മണിക്കൂർ",hh:"%d മണിക്കൂർ",d:"ഒരു ദിവസം",dd:"%d ദിവസം",M:"ഒരു മാസം",MM:"%d മാസം",y:"ഒരു വർഷം",yy:"%d വർഷം"},meridiemParse:/രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,meridiemHour:function(e,t){if(e===12)e=0;if(t==="രാത്രി"&&e>=4||t==="ഉച്ച കഴിഞ്ഞ്"||t==="വൈകുന്നേരം")return e+12;else return e},meridiem:function(e,t,n){if(e<4)return"രാത്രി";else if(e<12)return"രാവിലെ";else if(e<17)return"ഉച്ച കഴിഞ്ഞ്";else if(e<20)return"വൈകുന്നേരം";else return"രാത്രി"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){switch(n){case"s":return t?"хэдхэн секунд":"хэдхэн секундын";case"ss":return e+(t?" секунд":" секундын");case"m":case"mm":return e+(t?" минут":" минутын");case"h":case"hh":return e+(t?" цаг":" цагийн");case"d":case"dd":return e+(t?" өдөр":" өдрийн");case"M":case"MM":return e+(t?" сар":" сарын");case"y":case"yy":return e+(t?" жил":" жилийн");default:return e}}var n;e.defineLocale("mn",{months:"Нэгдүгээр сар_Хоёрдугаар сар_Гуравдугаар сар_Дөрөвдүгээр сар_Тавдугаар сар_Зургадугаар сар_Долдугаар сар_Наймдугаар сар_Есдүгээр сар_Аравдугаар сар_Арван нэгдүгээр сар_Арван хоёрдугаар сар".split("_"),monthsShort:"1 сар_2 сар_3 сар_4 сар_5 сар_6 сар_7 сар_8 сар_9 сар_10 сар_11 сар_12 сар".split("_"),monthsParseExact:true,weekdays:"Ням_Даваа_Мягмар_Лхагва_Пүрэв_Баасан_Бямба".split("_"),weekdaysShort:"Ням_Дав_Мяг_Лха_Пүр_Баа_Бям".split("_"),weekdaysMin:"Ня_Да_Мя_Лх_Пү_Ба_Бя".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY оны MMMMын D",LLL:"YYYY оны MMMMын D HH:mm",LLLL:"dddd, YYYY оны MMMMын D HH:mm"},meridiemParse:/ҮӨ|ҮХ/i,isPM:function(e){return e==="ҮХ"},meridiem:function(e,t,n){if(e<12)return"ҮӨ";else return"ҮХ"},calendar:{sameDay:"[Өнөөдөр] LT",nextDay:"[Маргааш] LT",nextWeek:"[Ирэх] dddd LT",lastDay:"[Өчигдөр] LT",lastWeek:"[Өнгөрсөн] dddd LT",sameElse:"L"},relativeTime:{future:"%s дараа",past:"%s өмнө",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2} өдөр/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+" өдөр";default:return e}}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},n={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},a;function r(e,t,n,a){var r="";if(t)switch(n){case"s":r="काही सेकंद";break;case"ss":r="%d सेकंद";break;case"m":r="एक मिनिट";break;case"mm":r="%d मिनिटे";break;case"h":r="एक तास";break;case"hh":r="%d तास";break;case"d":r="एक दिवस";break;case"dd":r="%d दिवस";break;case"M":r="एक महिना";break;case"MM":r="%d महिने";break;case"y":r="एक वर्ष";break;case"yy":r="%d वर्षे";break}else switch(n){case"s":r="काही सेकंदां";break;case"ss":r="%d सेकंदां";break;case"m":r="एका मिनिटा";break;case"mm":r="%d मिनिटां";break;case"h":r="एका तासा";break;case"hh":r="%d तासां";break;case"d":r="एका दिवसा";break;case"dd":r="%d दिवसां";break;case"M":r="एका महिन्या";break;case"MM":r="%d महिन्यां";break;case"y":r="एका वर्षा";break;case"yy":r="%d वर्षां";break}return r.replace(/%d/i,e)}e.defineLocale("mr",{months:"जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर".split("_"),monthsShort:"जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.".split("_"),monthsParseExact:true,weekdays:"रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार".split("_"),weekdaysShort:"रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि".split("_"),weekdaysMin:"र_सो_मं_बु_गु_शु_श".split("_"),longDateFormat:{LT:"A h:mm वाजता",LTS:"A h:mm:ss वाजता",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm वाजता",LLLL:"dddd, D MMMM YYYY, A h:mm वाजता"},calendar:{sameDay:"[आज] LT",nextDay:"[उद्या] LT",nextWeek:"dddd, LT",lastDay:"[काल] LT",lastWeek:"[मागील] dddd, LT",sameElse:"L"},relativeTime:{future:"%sमध्ये",past:"%sपूर्वी",s:r,ss:r,m:r,mm:r,h:r,hh:r,d:r,dd:r,M:r,MM:r,y:r,yy:r},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/पहाटे|सकाळी|दुपारी|सायंकाळी|रात्री/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="पहाटे"||t==="सकाळी")return e;else if(t==="दुपारी"||t==="सायंकाळी"||t==="रात्री")return e>=12?e:e+12},meridiem:function(e,t,n){if(e>=0&&e<6)return"पहाटे";else if(e<12)return"सकाळी";else if(e<17)return"दुपारी";else if(e<20)return"सायंकाळी";else return"रात्री"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ms",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="pagi")return e;else if(t==="tengahari")return e>=11?e:e+12;else if(t==="petang"||t==="malam")return e+12},meridiem:function(e,t,n){if(e<11)return"pagi";else if(e<15)return"tengahari";else if(e<19)return"petang";else return"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ms-my",{months:"Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis".split("_"),weekdays:"Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu".split("_"),weekdaysShort:"Ahd_Isn_Sel_Rab_Kha_Jum_Sab".split("_"),weekdaysMin:"Ah_Is_Sl_Rb_Km_Jm_Sb".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [pukul] HH.mm",LLLL:"dddd, D MMMM YYYY [pukul] HH.mm"},meridiemParse:/pagi|tengahari|petang|malam/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="pagi")return e;else if(t==="tengahari")return e>=11?e:e+12;else if(t==="petang"||t==="malam")return e+12},meridiem:function(e,t,n){if(e<11)return"pagi";else if(e<15)return"tengahari";else if(e<19)return"petang";else return"malam"},calendar:{sameDay:"[Hari ini pukul] LT",nextDay:"[Esok pukul] LT",nextWeek:"dddd [pukul] LT",lastDay:"[Kelmarin pukul] LT",lastWeek:"dddd [lepas pukul] LT",sameElse:"L"},relativeTime:{future:"dalam %s",past:"%s yang lepas",s:"beberapa saat",ss:"%d saat",m:"seminit",mm:"%d minit",h:"sejam",hh:"%d jam",d:"sehari",dd:"%d hari",M:"sebulan",MM:"%d bulan",y:"setahun",yy:"%d tahun"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("mt",{months:"Jannar_Frar_Marzu_April_Mejju_Ġunju_Lulju_Awwissu_Settembru_Ottubru_Novembru_Diċembru".split("_"),monthsShort:"Jan_Fra_Mar_Apr_Mej_Ġun_Lul_Aww_Set_Ott_Nov_Diċ".split("_"),weekdays:"Il-Ħadd_It-Tnejn_It-Tlieta_L-Erbgħa_Il-Ħamis_Il-Ġimgħa_Is-Sibt".split("_"),weekdaysShort:"Ħad_Tne_Tli_Erb_Ħam_Ġim_Sib".split("_"),weekdaysMin:"Ħa_Tn_Tl_Er_Ħa_Ġi_Si".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Illum fil-]LT",nextDay:"[Għada fil-]LT",nextWeek:"dddd [fil-]LT",lastDay:"[Il-bieraħ fil-]LT",lastWeek:"dddd [li għadda] [fil-]LT",sameElse:"L"},relativeTime:{future:"f’ %s",past:"%s ilu",s:"ftit sekondi",ss:"%d sekondi",m:"minuta",mm:"%d minuti",h:"siegħa",hh:"%d siegħat",d:"ġurnata",dd:"%d ġranet",M:"xahar",MM:"%d xhur",y:"sena",yy:"%d sni"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"၁",2:"၂",3:"၃",4:"၄",5:"၅",6:"၆",7:"၇",8:"၈",9:"၉",0:"၀"},n={"၁":"1","၂":"2","၃":"3","၄":"4","၅":"5","၆":"6","၇":"7","၈":"8","၉":"9","၀":"0"},a;e.defineLocale("my",{months:"ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ".split("_"),monthsShort:"ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ".split("_"),weekdays:"တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ".split("_"),weekdaysShort:"နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),weekdaysMin:"နွေ_လာ_ဂါ_ဟူး_ကြာ_သော_နေ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[ယနေ.] LT [မှာ]",nextDay:"[မနက်ဖြန်] LT [မှာ]",nextWeek:"dddd LT [မှာ]",lastDay:"[မနေ.က] LT [မှာ]",lastWeek:"[ပြီးခဲ့သော] dddd LT [မှာ]",sameElse:"L"},relativeTime:{future:"လာမည့် %s မှာ",past:"လွန်ခဲ့သော %s က",s:"စက္ကန်.အနည်းငယ်",ss:"%d စက္ကန့်",m:"တစ်မိနစ်",mm:"%d မိနစ်",h:"တစ်နာရီ",hh:"%d နာရီ",d:"တစ်ရက်",dd:"%d ရက်",M:"တစ်လ",MM:"%d လ",y:"တစ်နှစ်",yy:"%d နှစ်"},preparse:function(e){return e.replace(/[၁၂၃၄၅၆၇၈၉၀]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("nb",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:true,weekdays:"søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag".split("_"),weekdaysShort:"sø._ma._ti._on._to._fr._lø.".split("_"),weekdaysMin:"sø_ma_ti_on_to_fr_lø".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] HH:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[i dag kl.] LT",nextDay:"[i morgen kl.] LT",nextWeek:"dddd [kl.] LT",lastDay:"[i går kl.] LT",lastWeek:"[forrige] dddd [kl.] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s siden",s:"noen sekunder",ss:"%d sekunder",m:"ett minutt",mm:"%d minutter",h:"en time",hh:"%d timer",d:"en dag",dd:"%d dager",w:"en uke",ww:"%d uker",M:"en måned",MM:"%d måneder",y:"ett år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"१",2:"२",3:"३",4:"४",5:"५",6:"६",7:"७",8:"८",9:"९",0:"०"},n={"१":"1","२":"2","३":"3","४":"4","५":"5","६":"6","७":"7","८":"8","९":"9","०":"0"},a;e.defineLocale("ne",{months:"जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर".split("_"),monthsShort:"जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.".split("_"),monthsParseExact:true,weekdays:"आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार".split("_"),weekdaysShort:"आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.".split("_"),weekdaysMin:"आ._सो._मं._बु._बि._शु._श.".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"Aको h:mm बजे",LTS:"Aको h:mm:ss बजे",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, Aको h:mm बजे",LLLL:"dddd, D MMMM YYYY, Aको h:mm बजे"},preparse:function(e){return e.replace(/[१२३४५६७८९०]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/राति|बिहान|दिउँसो|साँझ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="राति")return e<4?e:e+12;else if(t==="बिहान")return e;else if(t==="दिउँसो")return e>=10?e:e+12;else if(t==="साँझ")return e+12},meridiem:function(e,t,n){if(e<3)return"राति";else if(e<12)return"बिहान";else if(e<16)return"दिउँसो";else if(e<20)return"साँझ";else return"राति"},calendar:{sameDay:"[आज] LT",nextDay:"[भोलि] LT",nextWeek:"[आउँदो] dddd[,] LT",lastDay:"[हिजो] LT",lastWeek:"[गएको] dddd[,] LT",sameElse:"L"},relativeTime:{future:"%sमा",past:"%s अगाडि",s:"केही क्षण",ss:"%d सेकेण्ड",m:"एक मिनेट",mm:"%d मिनेट",h:"एक घण्टा",hh:"%d घण्टा",d:"एक दिन",dd:"%d दिन",M:"एक महिना",MM:"%d महिना",y:"एक बर्ष",yy:"%d बर्ष"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),a="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),t=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],r=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,o;e.defineLocale("nl",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD-MM-YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",w:"één week",ww:"%d weken",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(e===1||e===8||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),a="jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec".split("_"),t=[/^jan/i,/^feb/i,/^maart|mrt.?$/i,/^apr/i,/^mei$/i,/^jun[i.]?$/i,/^jul[i.]?$/i,/^aug/i,/^sep/i,/^okt/i,/^nov/i,/^dec/i],r=/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,o;e.defineLocale("nl-be",{months:"januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december".split("_"),monthsShort:function(e,t){if(!e)return n;else if(/-MMM-/.test(t))return a[e.month()];else return n[e.month()]},monthsRegex:r,monthsShortRegex:r,monthsStrictRegex:/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,monthsShortStrictRegex:/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag".split("_"),weekdaysShort:"zo._ma._di._wo._do._vr._za.".split("_"),weekdaysMin:"zo_ma_di_wo_do_vr_za".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[vandaag om] LT",nextDay:"[morgen om] LT",nextWeek:"dddd [om] LT",lastDay:"[gisteren om] LT",lastWeek:"[afgelopen] dddd [om] LT",sameElse:"L"},relativeTime:{future:"over %s",past:"%s geleden",s:"een paar seconden",ss:"%d seconden",m:"één minuut",mm:"%d minuten",h:"één uur",hh:"%d uur",d:"één dag",dd:"%d dagen",M:"één maand",MM:"%d maanden",y:"één jaar",yy:"%d jaar"},dayOfMonthOrdinalParse:/\d{1,2}(ste|de)/,ordinal:function(e){return e+(e===1||e===8||e>=20?"ste":"de")},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("nn",{months:"januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember".split("_"),monthsShort:"jan._feb._mars_apr._mai_juni_juli_aug._sep._okt._nov._des.".split("_"),monthsParseExact:true,weekdays:"sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag".split("_"),weekdaysShort:"su._må._ty._on._to._fr._lau.".split("_"),weekdaysMin:"su_må_ty_on_to_fr_la".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY [kl.] H:mm",LLLL:"dddd D. MMMM YYYY [kl.] HH:mm"},calendar:{sameDay:"[I dag klokka] LT",nextDay:"[I morgon klokka] LT",nextWeek:"dddd [klokka] LT",lastDay:"[I går klokka] LT",lastWeek:"[Føregåande] dddd [klokka] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"%s sidan",s:"nokre sekund",ss:"%d sekund",m:"eit minutt",mm:"%d minutt",h:"ein time",hh:"%d timar",d:"ein dag",dd:"%d dagar",w:"ei veke",ww:"%d veker",M:"ein månad",MM:"%d månader",y:"eit år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("oc-lnc",{months:{standalone:"genièr_febrièr_març_abril_mai_junh_julhet_agost_setembre_octòbre_novembre_decembre".split("_"),format:"de genièr_de febrièr_de març_d'abril_de mai_de junh_de julhet_d'agost_de setembre_d'octòbre_de novembre_de decembre".split("_"),isFormat:/D[oD]?(\s)+MMMM/},monthsShort:"gen._febr._març_abr._mai_junh_julh._ago._set._oct._nov._dec.".split("_"),monthsParseExact:true,weekdays:"dimenge_diluns_dimars_dimècres_dijòus_divendres_dissabte".split("_"),weekdaysShort:"dg._dl._dm._dc._dj._dv._ds.".split("_"),weekdaysMin:"dg_dl_dm_dc_dj_dv_ds".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [de] YYYY",ll:"D MMM YYYY",LLL:"D MMMM [de] YYYY [a] H:mm",lll:"D MMM YYYY, H:mm",LLLL:"dddd D MMMM [de] YYYY [a] H:mm",llll:"ddd D MMM YYYY, H:mm"},calendar:{sameDay:"[uèi a] LT",nextDay:"[deman a] LT",nextWeek:"dddd [a] LT",lastDay:"[ièr a] LT",lastWeek:"dddd [passat a] LT",sameElse:"L"},relativeTime:{future:"d'aquí %s",past:"fa %s",s:"unas segondas",ss:"%d segondas",m:"una minuta",mm:"%d minutas",h:"una ora",hh:"%d oras",d:"un jorn",dd:"%d jorns",M:"un mes",MM:"%d meses",y:"un an",yy:"%d ans"},dayOfMonthOrdinalParse:/\d{1,2}(r|n|t|è|a)/,ordinal:function(e,t){var n=e===1?"r":e===2?"n":e===3?"r":e===4?"t":"è";if(t==="w"||t==="W")n="a";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"੧",2:"੨",3:"੩",4:"੪",5:"੫",6:"੬",7:"੭",8:"੮",9:"੯",0:"੦"},n={"੧":"1","੨":"2","੩":"3","੪":"4","੫":"5","੬":"6","੭":"7","੮":"8","੯":"9","੦":"0"},a;e.defineLocale("pa-in",{months:"ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ".split("_"),monthsShort:"ਜਨਵਰੀ_ਫ਼ਰਵਰੀ_ਮਾਰਚ_ਅਪ੍ਰੈਲ_ਮਈ_ਜੂਨ_ਜੁਲਾਈ_ਅਗਸਤ_ਸਤੰਬਰ_ਅਕਤੂਬਰ_ਨਵੰਬਰ_ਦਸੰਬਰ".split("_"),weekdays:"ਐਤਵਾਰ_ਸੋਮਵਾਰ_ਮੰਗਲਵਾਰ_ਬੁਧਵਾਰ_ਵੀਰਵਾਰ_ਸ਼ੁੱਕਰਵਾਰ_ਸ਼ਨੀਚਰਵਾਰ".split("_"),weekdaysShort:"ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ".split("_"),weekdaysMin:"ਐਤ_ਸੋਮ_ਮੰਗਲ_ਬੁਧ_ਵੀਰ_ਸ਼ੁਕਰ_ਸ਼ਨੀ".split("_"),longDateFormat:{LT:"A h:mm ਵਜੇ",LTS:"A h:mm:ss ਵਜੇ",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm ਵਜੇ",LLLL:"dddd, D MMMM YYYY, A h:mm ਵਜੇ"},calendar:{sameDay:"[ਅਜ] LT",nextDay:"[ਕਲ] LT",nextWeek:"[ਅਗਲਾ] dddd, LT",lastDay:"[ਕਲ] LT",lastWeek:"[ਪਿਛਲੇ] dddd, LT",sameElse:"L"},relativeTime:{future:"%s ਵਿੱਚ",past:"%s ਪਿਛਲੇ",s:"ਕੁਝ ਸਕਿੰਟ",ss:"%d ਸਕਿੰਟ",m:"ਇਕ ਮਿੰਟ",mm:"%d ਮਿੰਟ",h:"ਇੱਕ ਘੰਟਾ",hh:"%d ਘੰਟੇ",d:"ਇੱਕ ਦਿਨ",dd:"%d ਦਿਨ",M:"ਇੱਕ ਮਹੀਨਾ",MM:"%d ਮਹੀਨੇ",y:"ਇੱਕ ਸਾਲ",yy:"%d ਸਾਲ"},preparse:function(e){return e.replace(/[੧੨੩੪੫੬੭੮੯੦]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/ਰਾਤ|ਸਵੇਰ|ਦੁਪਹਿਰ|ਸ਼ਾਮ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="ਰਾਤ")return e<4?e:e+12;else if(t==="ਸਵੇਰ")return e;else if(t==="ਦੁਪਹਿਰ")return e>=10?e:e+12;else if(t==="ਸ਼ਾਮ")return e+12},meridiem:function(e,t,n){if(e<4)return"ਰਾਤ";else if(e<10)return"ਸਵੇਰ";else if(e<17)return"ਦੁਪਹਿਰ";else if(e<20)return"ਸ਼ਾਮ";else return"ਰਾਤ"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var n="styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień".split("_"),a="stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia".split("_"),t=[/^sty/i,/^lut/i,/^mar/i,/^kwi/i,/^maj/i,/^cze/i,/^lip/i,/^sie/i,/^wrz/i,/^paź/i,/^lis/i,/^gru/i],r;function o(e){return e%10<5&&e%10>1&&~~(e/10)%10!==1}function i(e,t,n){var a=e+" ";switch(n){case"ss":return a+(o(e)?"sekundy":"sekund");case"m":return t?"minuta":"minutę";case"mm":return a+(o(e)?"minuty":"minut");case"h":return t?"godzina":"godzinę";case"hh":return a+(o(e)?"godziny":"godzin");case"ww":return a+(o(e)?"tygodnie":"tygodni");case"MM":return a+(o(e)?"miesiące":"miesięcy");case"yy":return a+(o(e)?"lata":"lat")}}e.defineLocale("pl",{months:function(e,t){if(!e)return n;else if(/D MMMM/.test(t))return a[e.month()];else return n[e.month()]},monthsShort:"sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru".split("_"),monthsParse:t,longMonthsParse:t,shortMonthsParse:t,weekdays:"niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota".split("_"),weekdaysShort:"ndz_pon_wt_śr_czw_pt_sob".split("_"),weekdaysMin:"Nd_Pn_Wt_Śr_Cz_Pt_So".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Dziś o] LT",nextDay:"[Jutro o] LT",nextWeek:function(){switch(this.day()){case 0:return"[W niedzielę o] LT";case 2:return"[We wtorek o] LT";case 3:return"[W środę o] LT";case 6:return"[W sobotę o] LT";default:return"[W] dddd [o] LT"}},lastDay:"[Wczoraj o] LT",lastWeek:function(){switch(this.day()){case 0:return"[W zeszłą niedzielę o] LT";case 3:return"[W zeszłą środę o] LT";case 6:return"[W zeszłą sobotę o] LT";default:return"[W zeszły] dddd [o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"%s temu",s:"kilka sekund",ss:i,m:i,mm:i,h:i,hh:i,d:"1 dzień",dd:"%d dni",w:"tydzień",ww:i,M:"miesiąc",MM:i,y:"rok",yy:i},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("pt",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado".split("_"),weekdaysShort:"Dom_Seg_Ter_Qua_Qui_Sex_Sáb".split("_"),weekdaysMin:"Do_2ª_3ª_4ª_5ª_6ª_Sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return this.day()===0||this.day()===6?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",w:"uma semana",ww:"%d semanas",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("pt-br",{months:"janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro".split("_"),monthsShort:"jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez".split("_"),weekdays:"domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado".split("_"),weekdaysShort:"dom_seg_ter_qua_qui_sex_sáb".split("_"),weekdaysMin:"do_2ª_3ª_4ª_5ª_6ª_sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D [de] MMMM [de] YYYY",LLL:"D [de] MMMM [de] YYYY [às] HH:mm",LLLL:"dddd, D [de] MMMM [de] YYYY [às] HH:mm"},calendar:{sameDay:"[Hoje às] LT",nextDay:"[Amanhã às] LT",nextWeek:"dddd [às] LT",lastDay:"[Ontem às] LT",lastWeek:function(){return this.day()===0||this.day()===6?"[Último] dddd [às] LT":"[Última] dddd [às] LT"},sameElse:"L"},relativeTime:{future:"em %s",past:"há %s",s:"poucos segundos",ss:"%d segundos",m:"um minuto",mm:"%d minutos",h:"uma hora",hh:"%d horas",d:"um dia",dd:"%d dias",M:"um mês",MM:"%d meses",y:"um ano",yy:"%d anos"},dayOfMonthOrdinalParse:/\d{1,2}º/,ordinal:"%dº",invalidDate:"Data inválida"})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n){var a={ss:"secunde",mm:"minute",hh:"ore",dd:"zile",ww:"săptămâni",MM:"luni",yy:"ani"},r=" ";if(e%100>=20||e>=100&&e%100===0)r=" de ";return e+r+a[n]}var n;e.defineLocale("ro",{months:"ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie".split("_"),monthsShort:"ian._feb._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.".split("_"),monthsParseExact:true,weekdays:"duminică_luni_marți_miercuri_joi_vineri_sâmbătă".split("_"),weekdaysShort:"Dum_Lun_Mar_Mie_Joi_Vin_Sâm".split("_"),weekdaysMin:"Du_Lu_Ma_Mi_Jo_Vi_Sâ".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY H:mm",LLLL:"dddd, D MMMM YYYY H:mm"},calendar:{sameDay:"[azi la] LT",nextDay:"[mâine la] LT",nextWeek:"dddd [la] LT",lastDay:"[ieri la] LT",lastWeek:"[fosta] dddd [la] LT",sameElse:"L"},relativeTime:{future:"peste %s",past:"%s în urmă",s:"câteva secunde",ss:t,m:"un minut",mm:t,h:"o oră",hh:t,d:"o zi",dd:t,w:"o săptămână",ww:t,M:"o lună",MM:t,y:"un an",yy:t},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function r(e,t){var n=e.split("_");return t%10===1&&t%100!==11?n[0]:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?n[1]:n[2]}function t(e,t,n){var a={ss:t?"секунда_секунды_секунд":"секунду_секунды_секунд",mm:t?"минута_минуты_минут":"минуту_минуты_минут",hh:"час_часа_часов",dd:"день_дня_дней",ww:"неделя_недели_недель",MM:"месяц_месяца_месяцев",yy:"год_года_лет"};if(n==="m")return t?"минута":"минуту";else return e+" "+r(a[n],+e)}var n=[/^янв/i,/^фев/i,/^мар/i,/^апр/i,/^ма[йя]/i,/^июн/i,/^июл/i,/^авг/i,/^сен/i,/^окт/i,/^ноя/i,/^дек/i],a;e.defineLocale("ru",{months:{format:"января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря".split("_"),standalone:"январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь".split("_")},monthsShort:{format:"янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.".split("_"),standalone:"янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.".split("_")},weekdays:{standalone:"воскресенье_понедельник_вторник_среда_четверг_пятница_суббота".split("_"),format:"воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу".split("_"),isFormat:/\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?] ?dddd/},weekdaysShort:"вс_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"вс_пн_вт_ср_чт_пт_сб".split("_"),monthsParse:n,longMonthsParse:n,shortMonthsParse:n,monthsRegex:/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,monthsShortRegex:/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,monthsStrictRegex:/^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,monthsShortStrictRegex:/^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY г.",LLL:"D MMMM YYYY г., H:mm",LLLL:"dddd, D MMMM YYYY г., H:mm"},calendar:{sameDay:"[Сегодня, в] LT",nextDay:"[Завтра, в] LT",lastDay:"[Вчера, в] LT",nextWeek:function(e){if(e.week()!==this.week())switch(this.day()){case 0:return"[В следующее] dddd, [в] LT";case 1:case 2:case 4:return"[В следующий] dddd, [в] LT";case 3:case 5:case 6:return"[В следующую] dddd, [в] LT"}else if(this.day()===2)return"[Во] dddd, [в] LT";else return"[В] dddd, [в] LT"},lastWeek:function(e){if(e.week()!==this.week())switch(this.day()){case 0:return"[В прошлое] dddd, [в] LT";case 1:case 2:case 4:return"[В прошлый] dddd, [в] LT";case 3:case 5:case 6:return"[В прошлую] dddd, [в] LT"}else if(this.day()===2)return"[Во] dddd, [в] LT";else return"[В] dddd, [в] LT"},sameElse:"L"},relativeTime:{future:"через %s",past:"%s назад",s:"несколько секунд",ss:t,m:t,mm:t,h:"час",hh:t,d:"день",dd:t,w:"неделя",ww:t,M:"месяц",MM:t,y:"год",yy:t},meridiemParse:/ночи|утра|дня|вечера/i,isPM:function(e){return/^(дня|вечера)$/.test(e)},meridiem:function(e,t,n){if(e<4)return"ночи";else if(e<12)return"утра";else if(e<17)return"дня";else return"вечера"},dayOfMonthOrdinalParse:/\d{1,2}-(й|го|я)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":return e+"-й";case"D":return e+"-го";case"w":case"W":return e+"-я";default:return e}},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t=["جنوري","فيبروري","مارچ","اپريل","مئي","جون","جولاءِ","آگسٽ","سيپٽمبر","آڪٽوبر","نومبر","ڊسمبر"],n=["آچر","سومر","اڱارو","اربع","خميس","جمع","ڇنڇر"],a;e.defineLocale("sd",{months:t,monthsShort:t,weekdays:n,weekdaysShort:n,weekdaysMin:n,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd، D MMMM YYYY HH:mm"},meridiemParse:/صبح|شام/,isPM:function(e){return"شام"===e},meridiem:function(e,t,n){if(e<12)return"صبح";return"شام"},calendar:{sameDay:"[اڄ] LT",nextDay:"[سڀاڻي] LT",nextWeek:"dddd [اڳين هفتي تي] LT",lastDay:"[ڪالهه] LT",lastWeek:"[گزريل هفتي] dddd [تي] LT",sameElse:"L"},relativeTime:{future:"%s پوء",past:"%s اڳ",s:"چند سيڪنڊ",ss:"%d سيڪنڊ",m:"هڪ منٽ",mm:"%d منٽ",h:"هڪ ڪلاڪ",hh:"%d ڪلاڪ",d:"هڪ ڏينهن",dd:"%d ڏينهن",M:"هڪ مهينو",MM:"%d مهينا",y:"هڪ سال",yy:"%d سال"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("se",{months:"ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu".split("_"),monthsShort:"ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov".split("_"),weekdays:"sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat".split("_"),weekdaysShort:"sotn_vuos_maŋ_gask_duor_bear_láv".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s geažes",past:"maŋit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta mánnu",MM:"%d mánut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("si",{months:"ජනවාරි_පෙබරවාරි_මාර්තු_අප්‍රේල්_මැයි_ජූනි_ජූලි_අගෝස්තු_සැප්තැම්බර්_ඔක්තෝබර්_නොවැම්බර්_දෙසැම්බර්".split("_"),monthsShort:"ජන_පෙබ_මාර්_අප්_මැයි_ජූනි_ජූලි_අගෝ_සැප්_ඔක්_නොවැ_දෙසැ".split("_"),weekdays:"ඉරිදා_සඳුදා_අඟහරුවාදා_බදාදා_බ්‍රහස්පතින්දා_සිකුරාදා_සෙනසුරාදා".split("_"),weekdaysShort:"ඉරි_සඳු_අඟ_බදා_බ්‍රහ_සිකු_සෙන".split("_"),weekdaysMin:"ඉ_ස_අ_බ_බ්‍ර_සි_සෙ".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"a h:mm",LTS:"a h:mm:ss",L:"YYYY/MM/DD",LL:"YYYY MMMM D",LLL:"YYYY MMMM D, a h:mm",LLLL:"YYYY MMMM D [වැනි] dddd, a h:mm:ss"},calendar:{sameDay:"[අද] LT[ට]",nextDay:"[හෙට] LT[ට]",nextWeek:"dddd LT[ට]",lastDay:"[ඊයේ] LT[ට]",lastWeek:"[පසුගිය] dddd LT[ට]",sameElse:"L"},relativeTime:{future:"%sකින්",past:"%sකට පෙර",s:"තත්පර කිහිපය",ss:"තත්පර %d",m:"මිනිත්තුව",mm:"මිනිත්තු %d",h:"පැය",hh:"පැය %d",d:"දිනය",dd:"දින %d",M:"මාසය",MM:"මාස %d",y:"වසර",yy:"වසර %d"},dayOfMonthOrdinalParse:/\d{1,2} වැනි/,ordinal:function(e){return e+" වැනි"},meridiemParse:/පෙර වරු|පස් වරු|පෙ.ව|ප.ව./,isPM:function(e){return e==="ප.ව."||e==="පස් වරු"},meridiem:function(e,t,n){if(e>11)return n?"ප.ව.":"පස් වරු";else return n?"පෙ.ව.":"පෙර වරු"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t="január_február_marec_apríl_máj_jún_júl_august_september_október_november_december".split("_"),n="jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec".split("_"),a;function o(e){return e>1&&e<5}function r(e,t,n,a){var r=e+" ";switch(n){case"s":return t||a?"pár sekúnd":"pár sekundami";case"ss":if(t||a)return r+(o(e)?"sekundy":"sekúnd");else return r+"sekundami";case"m":return t?"minúta":a?"minútu":"minútou";case"mm":if(t||a)return r+(o(e)?"minúty":"minút");else return r+"minútami";case"h":return t?"hodina":a?"hodinu":"hodinou";case"hh":if(t||a)return r+(o(e)?"hodiny":"hodín");else return r+"hodinami";case"d":return t||a?"deň":"dňom";case"dd":if(t||a)return r+(o(e)?"dni":"dní");else return r+"dňami";case"M":return t||a?"mesiac":"mesiacom";case"MM":if(t||a)return r+(o(e)?"mesiace":"mesiacov");else return r+"mesiacmi";case"y":return t||a?"rok":"rokom";case"yy":if(t||a)return r+(o(e)?"roky":"rokov");else return r+"rokmi"}}e.defineLocale("sk",{months:t,monthsShort:n,weekdays:"nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota".split("_"),weekdaysShort:"ne_po_ut_st_št_pi_so".split("_"),weekdaysMin:"ne_po_ut_st_št_pi_so".split("_"),longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD.MM.YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd D. MMMM YYYY H:mm"},calendar:{sameDay:"[dnes o] LT",nextDay:"[zajtra o] LT",nextWeek:function(){switch(this.day()){case 0:return"[v nedeľu o] LT";case 1:case 2:return"[v] dddd [o] LT";case 3:return"[v stredu o] LT";case 4:return"[vo štvrtok o] LT";case 5:return"[v piatok o] LT";case 6:return"[v sobotu o] LT"}},lastDay:"[včera o] LT",lastWeek:function(){switch(this.day()){case 0:return"[minulú nedeľu o] LT";case 1:case 2:return"[minulý] dddd [o] LT";case 3:return"[minulú stredu o] LT";case 4:case 5:return"[minulý] dddd [o] LT";case 6:return"[minulú sobotu o] LT"}},sameElse:"L"},relativeTime:{future:"za %s",past:"pred %s",s:r,ss:r,m:r,mm:r,h:r,hh:r,d:r,dd:r,M:r,MM:r,y:r,yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function t(e,t,n,a){var r=e+" ";switch(n){case"s":return t||a?"nekaj sekund":"nekaj sekundami";case"ss":if(e===1)r+=t?"sekundo":"sekundi";else if(e===2)r+=t||a?"sekundi":"sekundah";else if(e<5)r+=t||a?"sekunde":"sekundah";else r+="sekund";return r;case"m":return t?"ena minuta":"eno minuto";case"mm":if(e===1)r+=t?"minuta":"minuto";else if(e===2)r+=t||a?"minuti":"minutama";else if(e<5)r+=t||a?"minute":"minutami";else r+=t||a?"minut":"minutami";return r;case"h":return t?"ena ura":"eno uro";case"hh":if(e===1)r+=t?"ura":"uro";else if(e===2)r+=t||a?"uri":"urama";else if(e<5)r+=t||a?"ure":"urami";else r+=t||a?"ur":"urami";return r;case"d":return t||a?"en dan":"enim dnem";case"dd":if(e===1)r+=t||a?"dan":"dnem";else if(e===2)r+=t||a?"dni":"dnevoma";else r+=t||a?"dni":"dnevi";return r;case"M":return t||a?"en mesec":"enim mesecem";case"MM":if(e===1)r+=t||a?"mesec":"mesecem";else if(e===2)r+=t||a?"meseca":"mesecema";else if(e<5)r+=t||a?"mesece":"meseci";else r+=t||a?"mesecev":"meseci";return r;case"y":return t||a?"eno leto":"enim letom";case"yy":if(e===1)r+=t||a?"leto":"letom";else if(e===2)r+=t||a?"leti":"letoma";else if(e<5)r+=t||a?"leta":"leti";else r+=t||a?"let":"leti";return r}}var n;e.defineLocale("sl",{months:"januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december".split("_"),monthsShort:"jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.".split("_"),monthsParseExact:true,weekdays:"nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota".split("_"),weekdaysShort:"ned._pon._tor._sre._čet._pet._sob.".split("_"),weekdaysMin:"ne_po_to_sr_če_pe_so".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD. MM. YYYY",LL:"D. MMMM YYYY",LLL:"D. MMMM YYYY H:mm",LLLL:"dddd, D. MMMM YYYY H:mm"},calendar:{sameDay:"[danes ob] LT",nextDay:"[jutri ob] LT",nextWeek:function(){switch(this.day()){case 0:return"[v] [nedeljo] [ob] LT";case 3:return"[v] [sredo] [ob] LT";case 6:return"[v] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[v] dddd [ob] LT"}},lastDay:"[včeraj ob] LT",lastWeek:function(){switch(this.day()){case 0:return"[prejšnjo] [nedeljo] [ob] LT";case 3:return"[prejšnjo] [sredo] [ob] LT";case 6:return"[prejšnjo] [soboto] [ob] LT";case 1:case 2:case 4:case 5:return"[prejšnji] dddd [ob] LT"}},sameElse:"L"},relativeTime:{future:"čez %s",past:"pred %s",s:t,ss:t,m:t,mm:t,h:t,hh:t,d:t,dd:t,M:t,MM:t,y:t,yy:t},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("sq",{months:"Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor".split("_"),monthsShort:"Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj".split("_"),weekdays:"E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë".split("_"),weekdaysShort:"Die_Hën_Mar_Mër_Enj_Pre_Sht".split("_"),weekdaysMin:"D_H_Ma_Më_E_P_Sh".split("_"),weekdaysParseExact:true,meridiemParse:/PD|MD/,isPM:function(e){return e.charAt(0)==="M"},meridiem:function(e,t,n){return e<12?"PD":"MD"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Sot në] LT",nextDay:"[Nesër në] LT",nextWeek:"dddd [në] LT",lastDay:"[Dje në] LT",lastWeek:"dddd [e kaluar në] LT",sameElse:"L"},relativeTime:{future:"në %s",past:"%s më parë",s:"disa sekonda",ss:"%d sekonda",m:"një minutë",mm:"%d minuta",h:"një orë",hh:"%d orë",d:"një ditë",dd:"%d ditë",M:"një muaj",MM:"%d muaj",y:"një vit",yy:"%d vite"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var i={words:{ss:["sekunda","sekunde","sekundi"],m:["jedan minut","jednog minuta"],mm:["minut","minuta","minuta"],h:["jedan sat","jednog sata"],hh:["sat","sata","sati"],d:["jedan dan","jednog dana"],dd:["dan","dana","dana"],M:["jedan mesec","jednog meseca"],MM:["mesec","meseca","meseci"],y:["jednu godinu","jedne godine"],yy:["godinu","godine","godina"]},correctGrammaticalCase:function(e,t){if(e%10>=1&&e%10<=4&&(e%100<10||e%100>=20))return e%10===1?t[0]:t[1];return t[2]},translate:function(e,t,n,a){var r=i.words[n],o;if(n.length===1){if(n==="y"&&t)return"jedna godina";return a||t?r[0]:r[1]}o=i.correctGrammaticalCase(e,r);if(n==="yy"&&t&&o==="godinu")return e+" godina";return e+" "+o}},t;e.defineLocale("sr",{months:"januar_februar_mart_april_maj_jun_jul_avgust_septembar_oktobar_novembar_decembar".split("_"),monthsShort:"jan._feb._mar._apr._maj_jun_jul_avg._sep._okt._nov._dec.".split("_"),monthsParseExact:true,weekdays:"nedelja_ponedeljak_utorak_sreda_četvrtak_petak_subota".split("_"),weekdaysShort:"ned._pon._uto._sre._čet._pet._sub.".split("_"),weekdaysMin:"ne_po_ut_sr_če_pe_su".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D. M. YYYY.",LL:"D. MMMM YYYY.",LLL:"D. MMMM YYYY. H:mm",LLLL:"dddd, D. MMMM YYYY. H:mm"},calendar:{sameDay:"[danas u] LT",nextDay:"[sutra u] LT",nextWeek:function(){switch(this.day()){case 0:return"[u] [nedelju] [u] LT";case 3:return"[u] [sredu] [u] LT";case 6:return"[u] [subotu] [u] LT";case 1:case 2:case 4:case 5:return"[u] dddd [u] LT"}},lastDay:"[juče u] LT",lastWeek:function(){var e=["[prošle] [nedelje] [u] LT","[prošlog] [ponedeljka] [u] LT","[prošlog] [utorka] [u] LT","[prošle] [srede] [u] LT","[prošlog] [četvrtka] [u] LT","[prošlog] [petka] [u] LT","[prošle] [subote] [u] LT"];return e[this.day()]},sameElse:"L"},relativeTime:{future:"za %s",past:"pre %s",s:"nekoliko sekundi",ss:i.translate,m:i.translate,mm:i.translate,h:i.translate,hh:i.translate,d:i.translate,dd:i.translate,M:i.translate,MM:i.translate,y:i.translate,yy:i.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var i={words:{ss:["секунда","секунде","секунди"],m:["један минут","једног минута"],mm:["минут","минута","минута"],h:["један сат","једног сата"],hh:["сат","сата","сати"],d:["један дан","једног дана"],dd:["дан","дана","дана"],M:["један месец","једног месеца"],MM:["месец","месеца","месеци"],y:["једну годину","једне године"],yy:["годину","године","година"]},correctGrammaticalCase:function(e,t){if(e%10>=1&&e%10<=4&&(e%100<10||e%100>=20))return e%10===1?t[0]:t[1];return t[2]},translate:function(e,t,n,a){var r=i.words[n],o;if(n.length===1){if(n==="y"&&t)return"једна година";return a||t?r[0]:r[1]}o=i.correctGrammaticalCase(e,r);if(n==="yy"&&t&&o==="годину")return e+" година";return e+" "+o}},t;e.defineLocale("sr-cyrl",{months:"јануар_фебруар_март_април_мај_јун_јул_август_септембар_октобар_новембар_децембар".split("_"),monthsShort:"јан._феб._мар._апр._мај_јун_јул_авг._сеп._окт._нов._дец.".split("_"),monthsParseExact:true,weekdays:"недеља_понедељак_уторак_среда_четвртак_петак_субота".split("_"),weekdaysShort:"нед._пон._уто._сре._чет._пет._суб.".split("_"),weekdaysMin:"не_по_ут_ср_че_пе_су".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"D. M. YYYY.",LL:"D. MMMM YYYY.",LLL:"D. MMMM YYYY. H:mm",LLLL:"dddd, D. MMMM YYYY. H:mm"},calendar:{sameDay:"[данас у] LT",nextDay:"[сутра у] LT",nextWeek:function(){switch(this.day()){case 0:return"[у] [недељу] [у] LT";case 3:return"[у] [среду] [у] LT";case 6:return"[у] [суботу] [у] LT";case 1:case 2:case 4:case 5:return"[у] dddd [у] LT"}},lastDay:"[јуче у] LT",lastWeek:function(){var e=["[прошле] [недеље] [у] LT","[прошлог] [понедељка] [у] LT","[прошлог] [уторка] [у] LT","[прошле] [среде] [у] LT","[прошлог] [четвртка] [у] LT","[прошлог] [петка] [у] LT","[прошле] [суботе] [у] LT"];return e[this.day()]},sameElse:"L"},relativeTime:{future:"за %s",past:"пре %s",s:"неколико секунди",ss:i.translate,m:i.translate,mm:i.translate,h:i.translate,hh:i.translate,d:i.translate,dd:i.translate,M:i.translate,MM:i.translate,y:i.translate,yy:i.translate},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ss",{months:"Bhimbidvwane_Indlovana_Indlov'lenkhulu_Mabasa_Inkhwekhweti_Inhlaba_Kholwane_Ingci_Inyoni_Imphala_Lweti_Ingongoni".split("_"),monthsShort:"Bhi_Ina_Inu_Mab_Ink_Inh_Kho_Igc_Iny_Imp_Lwe_Igo".split("_"),weekdays:"Lisontfo_Umsombuluko_Lesibili_Lesitsatfu_Lesine_Lesihlanu_Umgcibelo".split("_"),weekdaysShort:"Lis_Umb_Lsb_Les_Lsi_Lsh_Umg".split("_"),weekdaysMin:"Li_Us_Lb_Lt_Ls_Lh_Ug".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Namuhla nga] LT",nextDay:"[Kusasa nga] LT",nextWeek:"dddd [nga] LT",lastDay:"[Itolo nga] LT",lastWeek:"dddd [leliphelile] [nga] LT",sameElse:"L"},relativeTime:{future:"nga %s",past:"wenteka nga %s",s:"emizuzwana lomcane",ss:"%d mzuzwana",m:"umzuzu",mm:"%d emizuzu",h:"lihora",hh:"%d emahora",d:"lilanga",dd:"%d emalanga",M:"inyanga",MM:"%d tinyanga",y:"umnyaka",yy:"%d iminyaka"},meridiemParse:/ekuseni|emini|entsambama|ebusuku/,meridiem:function(e,t,n){if(e<11)return"ekuseni";else if(e<15)return"emini";else if(e<19)return"entsambama";else return"ebusuku"},meridiemHour:function(e,t){if(e===12)e=0;if(t==="ekuseni")return e;else if(t==="emini")return e>=11?e:e+12;else if(t==="entsambama"||t==="ebusuku"){if(e===0)return 0;return e+12}},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:"%d",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("sv",{months:"januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december".split("_"),monthsShort:"jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec".split("_"),weekdays:"söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag".split("_"),weekdaysShort:"sön_mån_tis_ons_tor_fre_lör".split("_"),weekdaysMin:"sö_må_ti_on_to_fr_lö".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"D MMMM YYYY",LLL:"D MMMM YYYY [kl.] HH:mm",LLLL:"dddd D MMMM YYYY [kl.] HH:mm",lll:"D MMM YYYY HH:mm",llll:"ddd D MMM YYYY HH:mm"},calendar:{sameDay:"[Idag] LT",nextDay:"[Imorgon] LT",lastDay:"[Igår] LT",nextWeek:"[På] dddd LT",lastWeek:"[I] dddd[s] LT",sameElse:"L"},relativeTime:{future:"om %s",past:"för %s sedan",s:"några sekunder",ss:"%d sekunder",m:"en minut",mm:"%d minuter",h:"en timme",hh:"%d timmar",d:"en dag",dd:"%d dagar",M:"en månad",MM:"%d månader",y:"ett år",yy:"%d år"},dayOfMonthOrdinalParse:/\d{1,2}(\:e|\:a)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?":e":t===1?":a":t===2?":a":t===3?":e":":e";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("sw",{months:"Januari_Februari_Machi_Aprili_Mei_Juni_Julai_Agosti_Septemba_Oktoba_Novemba_Desemba".split("_"),monthsShort:"Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ago_Sep_Okt_Nov_Des".split("_"),weekdays:"Jumapili_Jumatatu_Jumanne_Jumatano_Alhamisi_Ijumaa_Jumamosi".split("_"),weekdaysShort:"Jpl_Jtat_Jnne_Jtan_Alh_Ijm_Jmos".split("_"),weekdaysMin:"J2_J3_J4_J5_Al_Ij_J1".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"hh:mm A",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[leo saa] LT",nextDay:"[kesho saa] LT",nextWeek:"[wiki ijayo] dddd [saat] LT",lastDay:"[jana] LT",lastWeek:"[wiki iliyopita] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s baadaye",past:"tokea %s",s:"hivi punde",ss:"sekunde %d",m:"dakika moja",mm:"dakika %d",h:"saa limoja",hh:"masaa %d",d:"siku moja",dd:"siku %d",M:"mwezi mmoja",MM:"miezi %d",y:"mwaka mmoja",yy:"miaka %d"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t={1:"௧",2:"௨",3:"௩",4:"௪",5:"௫",6:"௬",7:"௭",8:"௮",9:"௯",0:"௦"},n={"௧":"1","௨":"2","௩":"3","௪":"4","௫":"5","௬":"6","௭":"7","௮":"8","௯":"9","௦":"0"},a;e.defineLocale("ta",{months:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),monthsShort:"ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்".split("_"),weekdays:"ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை".split("_"),weekdaysShort:"ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி".split("_"),weekdaysMin:"ஞா_தி_செ_பு_வி_வெ_ச".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, HH:mm",LLLL:"dddd, D MMMM YYYY, HH:mm"},calendar:{sameDay:"[இன்று] LT",nextDay:"[நாளை] LT",nextWeek:"dddd, LT",lastDay:"[நேற்று] LT",lastWeek:"[கடந்த வாரம்] dddd, LT",sameElse:"L"},relativeTime:{future:"%s இல்",past:"%s முன்",s:"ஒரு சில விநாடிகள்",ss:"%d விநாடிகள்",m:"ஒரு நிமிடம்",mm:"%d நிமிடங்கள்",h:"ஒரு மணி நேரம்",hh:"%d மணி நேரம்",d:"ஒரு நாள்",dd:"%d நாட்கள்",M:"ஒரு மாதம்",MM:"%d மாதங்கள்",y:"ஒரு வருடம்",yy:"%d ஆண்டுகள்"},dayOfMonthOrdinalParse:/\d{1,2}வது/,ordinal:function(e){return e+"வது"},preparse:function(e){return e.replace(/[௧௨௩௪௫௬௭௮௯௦]/g,function(e){return n[e]})},postformat:function(e){return e.replace(/\d/g,function(e){return t[e]})},meridiemParse:/யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,meridiem:function(e,t,n){if(e<2)return" யாமம்";else if(e<6)return" வைகறை";else if(e<10)return" காலை";else if(e<14)return" நண்பகல்";else if(e<18)return" எற்பாடு";else if(e<22)return" மாலை";else return" யாமம்"},meridiemHour:function(e,t){if(e===12)e=0;if(t==="யாமம்")return e<2?e:e+12;else if(t==="வைகறை"||t==="காலை")return e;else if(t==="நண்பகல்")return e>=10?e:e+12;else return e+12},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("te",{months:"జనవరి_ఫిబ్రవరి_మార్చి_ఏప్రిల్_మే_జూన్_జులై_ఆగస్టు_సెప్టెంబర్_అక్టోబర్_నవంబర్_డిసెంబర్".split("_"),monthsShort:"జన._ఫిబ్ర._మార్చి_ఏప్రి._మే_జూన్_జులై_ఆగ._సెప్._అక్టో._నవ._డిసె.".split("_"),monthsParseExact:true,weekdays:"ఆదివారం_సోమవారం_మంగళవారం_బుధవారం_గురువారం_శుక్రవారం_శనివారం".split("_"),weekdaysShort:"ఆది_సోమ_మంగళ_బుధ_గురు_శుక్ర_శని".split("_"),weekdaysMin:"ఆ_సో_మం_బు_గు_శు_శ".split("_"),longDateFormat:{LT:"A h:mm",LTS:"A h:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY, A h:mm",LLLL:"dddd, D MMMM YYYY, A h:mm"},calendar:{sameDay:"[నేడు] LT",nextDay:"[రేపు] LT",nextWeek:"dddd, LT",lastDay:"[నిన్న] LT",lastWeek:"[గత] dddd, LT",sameElse:"L"},relativeTime:{future:"%s లో",past:"%s క్రితం",s:"కొన్ని క్షణాలు",ss:"%d సెకన్లు",m:"ఒక నిమిషం",mm:"%d నిమిషాలు",h:"ఒక గంట",hh:"%d గంటలు",d:"ఒక రోజు",dd:"%d రోజులు",M:"ఒక నెల",MM:"%d నెలలు",y:"ఒక సంవత్సరం",yy:"%d సంవత్సరాలు"},dayOfMonthOrdinalParse:/\d{1,2}వ/,ordinal:"%dవ",meridiemParse:/రాత్రి|ఉదయం|మధ్యాహ్నం|సాయంత్రం/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="రాత్రి")return e<4?e:e+12;else if(t==="ఉదయం")return e;else if(t==="మధ్యాహ్నం")return e>=10?e:e+12;else if(t==="సాయంత్రం")return e+12},meridiem:function(e,t,n){if(e<4)return"రాత్రి";else if(e<10)return"ఉదయం";else if(e<17)return"మధ్యాహ్నం";else if(e<20)return"సాయంత్రం";else return"రాత్రి"},week:{dow:0,doy:6}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("tet",{months:"Janeiru_Fevereiru_Marsu_Abril_Maiu_Juñu_Jullu_Agustu_Setembru_Outubru_Novembru_Dezembru".split("_"),monthsShort:"Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez".split("_"),weekdays:"Domingu_Segunda_Tersa_Kuarta_Kinta_Sesta_Sabadu".split("_"),weekdaysShort:"Dom_Seg_Ters_Kua_Kint_Sest_Sab".split("_"),weekdaysMin:"Do_Seg_Te_Ku_Ki_Ses_Sa".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Ohin iha] LT",nextDay:"[Aban iha] LT",nextWeek:"dddd [iha] LT",lastDay:"[Horiseik iha] LT",lastWeek:"dddd [semana kotuk] [iha] LT",sameElse:"L"},relativeTime:{future:"iha %s",past:"%s liuba",s:"segundu balun",ss:"segundu %d",m:"minutu ida",mm:"minutu %d",h:"oras ida",hh:"oras %d",d:"loron ida",dd:"loron %d",M:"fulan ida",MM:"fulan %d",y:"tinan ida",yy:"tinan %d"},dayOfMonthOrdinalParse:/\d{1,2}(st|nd|rd|th)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var a={0:"-ум",1:"-ум",2:"-юм",3:"-юм",4:"-ум",5:"-ум",6:"-ум",7:"-ум",8:"-ум",9:"-ум",10:"-ум",12:"-ум",13:"-ум",20:"-ум",30:"-юм",40:"-ум",50:"-ум",60:"-ум",70:"-ум",80:"-ум",90:"-ум",100:"-ум"},t;e.defineLocale("tg",{months:{format:"январи_феврали_марти_апрели_майи_июни_июли_августи_сентябри_октябри_ноябри_декабри".split("_"),standalone:"январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр".split("_")},monthsShort:"янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),weekdays:"якшанбе_душанбе_сешанбе_чоршанбе_панҷшанбе_ҷумъа_шанбе".split("_"),weekdaysShort:"яшб_дшб_сшб_чшб_пшб_ҷум_шнб".split("_"),weekdaysMin:"яш_дш_сш_чш_пш_ҷм_шб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[Имрӯз соати] LT",nextDay:"[Фардо соати] LT",lastDay:"[Дирӯз соати] LT",nextWeek:"dddd[и] [ҳафтаи оянда соати] LT",lastWeek:"dddd[и] [ҳафтаи гузашта соати] LT",sameElse:"L"},relativeTime:{future:"баъди %s",past:"%s пеш",s:"якчанд сония",m:"як дақиқа",mm:"%d дақиқа",h:"як соат",hh:"%d соат",d:"як рӯз",dd:"%d рӯз",M:"як моҳ",MM:"%d моҳ",y:"як сол",yy:"%d сол"},meridiemParse:/шаб|субҳ|рӯз|бегоҳ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="шаб")return e<4?e:e+12;else if(t==="субҳ")return e;else if(t==="рӯз")return e>=11?e:e+12;else if(t==="бегоҳ")return e+12},meridiem:function(e,t,n){if(e<4)return"шаб";else if(e<11)return"субҳ";else if(e<16)return"рӯз";else if(e<19)return"бегоҳ";else return"шаб"},dayOfMonthOrdinalParse:/\d{1,2}-(ум|юм)/,ordinal:function(e){var t=e%10,n=e>=100?100:null;return e+(a[e]||a[t]||a[n])},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("th",{months:"มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม".split("_"),monthsShort:"ม.ค._ก.พ._มี.ค._เม.ย._พ.ค._มิ.ย._ก.ค._ส.ค._ก.ย._ต.ค._พ.ย._ธ.ค.".split("_"),monthsParseExact:true,weekdays:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์".split("_"),weekdaysShort:"อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์".split("_"),weekdaysMin:"อา._จ._อ._พ._พฤ._ศ._ส.".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"H:mm",LTS:"H:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY เวลา H:mm",LLLL:"วันddddที่ D MMMM YYYY เวลา H:mm"},meridiemParse:/ก่อนเที่ยง|หลังเที่ยง/,isPM:function(e){return e==="หลังเที่ยง"},meridiem:function(e,t,n){if(e<12)return"ก่อนเที่ยง";else return"หลังเที่ยง"},calendar:{sameDay:"[วันนี้ เวลา] LT",nextDay:"[พรุ่งนี้ เวลา] LT",nextWeek:"dddd[หน้า เวลา] LT",lastDay:"[เมื่อวานนี้ เวลา] LT",lastWeek:"[วัน]dddd[ที่แล้ว เวลา] LT",sameElse:"L"},relativeTime:{future:"อีก %s",past:"%sที่แล้ว",s:"ไม่กี่วินาที",ss:"%d วินาที",m:"1 นาที",mm:"%d นาที",h:"1 ชั่วโมง",hh:"%d ชั่วโมง",d:"1 วัน",dd:"%d วัน",w:"1 สัปดาห์",ww:"%d สัปดาห์",M:"1 เดือน",MM:"%d เดือน",y:"1 ปี",yy:"%d ปี"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var o={1:"'inji",5:"'inji",8:"'inji",70:"'inji",80:"'inji",2:"'nji",7:"'nji",20:"'nji",50:"'nji",3:"'ünji",4:"'ünji",100:"'ünji",6:"'njy",9:"'unjy",10:"'unjy",30:"'unjy",60:"'ynjy",90:"'ynjy"},t;e.defineLocale("tk",{months:"Ýanwar_Fewral_Mart_Aprel_Maý_Iýun_Iýul_Awgust_Sentýabr_Oktýabr_Noýabr_Dekabr".split("_"),monthsShort:"Ýan_Few_Mar_Apr_Maý_Iýn_Iýl_Awg_Sen_Okt_Noý_Dek".split("_"),weekdays:"Ýekşenbe_Duşenbe_Sişenbe_Çarşenbe_Penşenbe_Anna_Şenbe".split("_"),weekdaysShort:"Ýek_Duş_Siş_Çar_Pen_Ann_Şen".split("_"),weekdaysMin:"Ýk_Dş_Sş_Çr_Pn_An_Şn".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün sagat] LT",nextDay:"[ertir sagat] LT",nextWeek:"[indiki] dddd [sagat] LT",lastDay:"[düýn] LT",lastWeek:"[geçen] dddd [sagat] LT",sameElse:"L"},relativeTime:{future:"%s soň",past:"%s öň",s:"birnäçe sekunt",m:"bir minut",mm:"%d minut",h:"bir sagat",hh:"%d sagat",d:"bir gün",dd:"%d gün",M:"bir aý",MM:"%d aý",y:"bir ýyl",yy:"%d ýyl"},ordinal:function(e,t){switch(t){case"d":case"D":case"Do":case"DD":return e;default:if(e===0)return e+"'unjy";var n=e%10,a=e%100-n,r=e>=100?100:null;return e+(o[n]||o[a]||o[r])}},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("tl-ph",{months:"Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre".split("_"),monthsShort:"Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis".split("_"),weekdays:"Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado".split("_"),weekdaysShort:"Lin_Lun_Mar_Miy_Huw_Biy_Sab".split("_"),weekdaysMin:"Li_Lu_Ma_Mi_Hu_Bi_Sab".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"MM/D/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY HH:mm",LLLL:"dddd, MMMM DD, YYYY HH:mm"},calendar:{sameDay:"LT [ngayong araw]",nextDay:"[Bukas ng] LT",nextWeek:"LT [sa susunod na] dddd",lastDay:"LT [kahapon]",lastWeek:"LT [noong nakaraang] dddd",sameElse:"L"},relativeTime:{future:"sa loob ng %s",past:"%s ang nakalipas",s:"ilang segundo",ss:"%d segundo",m:"isang minuto",mm:"%d minuto",h:"isang oras",hh:"%d oras",d:"isang araw",dd:"%d araw",M:"isang buwan",MM:"%d buwan",y:"isang taon",yy:"%d taon"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var o="pagh_wa’_cha’_wej_loS_vagh_jav_Soch_chorgh_Hut".split("_"),t;function n(e){var t=e;t=e.indexOf("jaj")!==-1?t.slice(0,-3)+"leS":e.indexOf("jar")!==-1?t.slice(0,-3)+"waQ":e.indexOf("DIS")!==-1?t.slice(0,-3)+"nem":t+" pIq";return t}function a(e){var t=e;t=e.indexOf("jaj")!==-1?t.slice(0,-3)+"Hu’":e.indexOf("jar")!==-1?t.slice(0,-3)+"wen":e.indexOf("DIS")!==-1?t.slice(0,-3)+"ben":t+" ret";return t}function r(e,t,n,a){var r=i(e);switch(n){case"ss":return r+" lup";case"mm":return r+" tup";case"hh":return r+" rep";case"dd":return r+" jaj";case"MM":return r+" jar";case"yy":return r+" DIS"}}function i(e){var t=Math.floor(e%1e3/100),n=Math.floor(e%100/10),a=e%10,r="";if(t>0)r+=o[t]+"vatlh";if(n>0)r+=(r!==""?" ":"")+o[n]+"maH";if(a>0)r+=(r!==""?" ":"")+o[a];return r===""?"pagh":r}e.defineLocale("tlh",{months:"tera’ jar wa’_tera’ jar cha’_tera’ jar wej_tera’ jar loS_tera’ jar vagh_tera’ jar jav_tera’ jar Soch_tera’ jar chorgh_tera’ jar Hut_tera’ jar wa’maH_tera’ jar wa’maH wa’_tera’ jar wa’maH cha’".split("_"),monthsShort:"jar wa’_jar cha’_jar wej_jar loS_jar vagh_jar jav_jar Soch_jar chorgh_jar Hut_jar wa’maH_jar wa’maH wa’_jar wa’maH cha’".split("_"),monthsParseExact:true,weekdays:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysShort:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),weekdaysMin:"lojmItjaj_DaSjaj_povjaj_ghItlhjaj_loghjaj_buqjaj_ghInjaj".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[DaHjaj] LT",nextDay:"[wa’leS] LT",nextWeek:"LLL",lastDay:"[wa’Hu’] LT",lastWeek:"LLL",sameElse:"L"},relativeTime:{future:n,past:a,s:"puS lup",ss:r,m:"wa’ tup",mm:r,h:"wa’ rep",hh:r,d:"wa’ jaj",dd:r,M:"wa’ jar",MM:r,y:"wa’ DIS",yy:r},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var o={1:"'inci",5:"'inci",8:"'inci",70:"'inci",80:"'inci",2:"'nci",7:"'nci",20:"'nci",50:"'nci",3:"'üncü",4:"'üncü",100:"'üncü",6:"'ncı",9:"'uncu",10:"'uncu",30:"'uncu",60:"'ıncı",90:"'ıncı"},t;e.defineLocale("tr",{months:"Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık".split("_"),monthsShort:"Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara".split("_"),weekdays:"Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi".split("_"),weekdaysShort:"Paz_Pzt_Sal_Çar_Per_Cum_Cmt".split("_"),weekdaysMin:"Pz_Pt_Sa_Ça_Pe_Cu_Ct".split("_"),meridiem:function(e,t,n){if(e<12)return n?"öö":"ÖÖ";else return n?"ös":"ÖS"},meridiemParse:/öö|ÖÖ|ös|ÖS/,isPM:function(e){return e==="ös"||e==="ÖS"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[bugün saat] LT",nextDay:"[yarın saat] LT",nextWeek:"[gelecek] dddd [saat] LT",lastDay:"[dün] LT",lastWeek:"[geçen] dddd [saat] LT",sameElse:"L"},relativeTime:{future:"%s sonra",past:"%s önce",s:"birkaç saniye",ss:"%d saniye",m:"bir dakika",mm:"%d dakika",h:"bir saat",hh:"%d saat",d:"bir gün",dd:"%d gün",w:"bir hafta",ww:"%d hafta",M:"bir ay",MM:"%d ay",y:"bir yıl",yy:"%d yıl"},ordinal:function(e,t){switch(t){case"d":case"D":case"Do":case"DD":return e;default:if(e===0)return e+"'ıncı";var n=e%10,a=e%100-n,r=e>=100?100:null;return e+(o[n]||o[a]||o[r])}},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;function n(e,t,n,a){var r={s:["viensas secunds","'iensas secunds"],ss:[e+" secunds",""+e+" secunds"],m:["'n míut","'iens míut"],mm:[e+" míuts",""+e+" míuts"],h:["'n þora","'iensa þora"],hh:[e+" þoras",""+e+" þoras"],d:["'n ziua","'iensa ziua"],dd:[e+" ziuas",""+e+" ziuas"],M:["'n mes","'iens mes"],MM:[e+" mesen",""+e+" mesen"],y:["'n ar","'iens ar"],yy:[e+" ars",""+e+" ars"]};return a?r[n][0]:t?r[n][0]:r[n][1]}e.defineLocale("tzl",{months:"Januar_Fevraglh_Març_Avrïu_Mai_Gün_Julia_Guscht_Setemvar_Listopäts_Noemvar_Zecemvar".split("_"),monthsShort:"Jan_Fev_Mar_Avr_Mai_Gün_Jul_Gus_Set_Lis_Noe_Zec".split("_"),weekdays:"Súladi_Lúneçi_Maitzi_Márcuri_Xhúadi_Viénerçi_Sáturi".split("_"),weekdaysShort:"Súl_Lún_Mai_Már_Xhú_Vié_Sát".split("_"),weekdaysMin:"Sú_Lú_Ma_Má_Xh_Vi_Sá".split("_"),longDateFormat:{LT:"HH.mm",LTS:"HH.mm.ss",L:"DD.MM.YYYY",LL:"D. MMMM [dallas] YYYY",LLL:"D. MMMM [dallas] YYYY HH.mm",LLLL:"dddd, [li] D. MMMM [dallas] YYYY HH.mm"},meridiemParse:/d\'o|d\'a/i,isPM:function(e){return"d'o"===e.toLowerCase()},meridiem:function(e,t,n){if(e>11)return n?"d'o":"D'O";else return n?"d'a":"D'A"},calendar:{sameDay:"[oxhi à] LT",nextDay:"[demà à] LT",nextWeek:"dddd [à] LT",lastDay:"[ieiri à] LT",lastWeek:"[sür el] dddd [lasteu à] LT",sameElse:"L"},relativeTime:{future:"osprei %s",past:"ja%s",s:n,ss:n,m:n,mm:n,h:n,hh:n,d:n,dd:n,M:n,MM:n,y:n,yy:n},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("tzm",{months:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),monthsShort:"ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ".split("_"),weekdays:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysShort:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),weekdaysMin:"ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[ⴰⵙⴷⵅ ⴴ] LT",nextDay:"[ⴰⵙⴽⴰ ⴴ] LT",nextWeek:"dddd [ⴴ] LT",lastDay:"[ⴰⵚⴰⵏⵜ ⴴ] LT",lastWeek:"dddd [ⴴ] LT",sameElse:"L"},relativeTime:{future:"ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s",past:"ⵢⴰⵏ %s",s:"ⵉⵎⵉⴽ",ss:"%d ⵉⵎⵉⴽ",m:"ⵎⵉⵏⵓⴺ",mm:"%d ⵎⵉⵏⵓⴺ",h:"ⵙⴰⵄⴰ",hh:"%d ⵜⴰⵙⵙⴰⵄⵉⵏ",d:"ⴰⵙⵙ",dd:"%d oⵙⵙⴰⵏ",M:"ⴰⵢoⵓⵔ",MM:"%d ⵉⵢⵢⵉⵔⵏ",y:"ⴰⵙⴳⴰⵙ",yy:"%d ⵉⵙⴳⴰⵙⵏ"},week:{dow:6,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("tzm-latn",{months:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),monthsShort:"innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir".split("_"),weekdays:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysShort:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),weekdaysMin:"asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd D MMMM YYYY HH:mm"},calendar:{sameDay:"[asdkh g] LT",nextDay:"[aska g] LT",nextWeek:"dddd [g] LT",lastDay:"[assant g] LT",lastWeek:"dddd [g] LT",sameElse:"L"},relativeTime:{future:"dadkh s yan %s",past:"yan %s",s:"imik",ss:"%d imik",m:"minuḍ",mm:"%d minuḍ",h:"saɛa",hh:"%d tassaɛin",d:"ass",dd:"%d ossan",M:"ayowr",MM:"%d iyyirn",y:"asgas",yy:"%d isgasn"},week:{dow:6,doy:12}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("ug-cn",{months:"يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر".split("_"),monthsShort:"يانۋار_فېۋرال_مارت_ئاپرېل_ماي_ئىيۇن_ئىيۇل_ئاۋغۇست_سېنتەبىر_ئۆكتەبىر_نويابىر_دېكابىر".split("_"),weekdays:"يەكشەنبە_دۈشەنبە_سەيشەنبە_چارشەنبە_پەيشەنبە_جۈمە_شەنبە".split("_"),weekdaysShort:"يە_دۈ_سە_چا_پە_جۈ_شە".split("_"),weekdaysMin:"يە_دۈ_سە_چا_پە_جۈ_شە".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY-MM-DD",LL:"YYYY-يىلىM-ئاينىڭD-كۈنى",LLL:"YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm",LLLL:"dddd، YYYY-يىلىM-ئاينىڭD-كۈنى، HH:mm"},meridiemParse:/يېرىم كېچە|سەھەر|چۈشتىن بۇرۇن|چۈش|چۈشتىن كېيىن|كەچ/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="يېرىم كېچە"||t==="سەھەر"||t==="چۈشتىن بۇرۇن")return e;else if(t==="چۈشتىن كېيىن"||t==="كەچ")return e+12;else return e>=11?e:e+12},meridiem:function(e,t,n){var a=e*100+t;if(a<600)return"يېرىم كېچە";else if(a<900)return"سەھەر";else if(a<1130)return"چۈشتىن بۇرۇن";else if(a<1230)return"چۈش";else if(a<1800)return"چۈشتىن كېيىن";else return"كەچ"},calendar:{sameDay:"[بۈگۈن سائەت] LT",nextDay:"[ئەتە سائەت] LT",nextWeek:"[كېلەركى] dddd [سائەت] LT",lastDay:"[تۆنۈگۈن] LT",lastWeek:"[ئالدىنقى] dddd [سائەت] LT",sameElse:"L"},relativeTime:{future:"%s كېيىن",past:"%s بۇرۇن",s:"نەچچە سېكونت",ss:"%d سېكونت",m:"بىر مىنۇت",mm:"%d مىنۇت",h:"بىر سائەت",hh:"%d سائەت",d:"بىر كۈن",dd:"%d كۈن",M:"بىر ئاي",MM:"%d ئاي",y:"بىر يىل",yy:"%d يىل"},dayOfMonthOrdinalParse:/\d{1,2}(-كۈنى|-ئاي|-ھەپتە)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"-كۈنى";case"w":case"W":return e+"-ھەپتە";default:return e}},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +function r(e,t){var n=e.split("_");return t%10===1&&t%100!==11?n[0]:t%10>=2&&t%10<=4&&(t%100<10||t%100>=20)?n[1]:n[2]}function t(e,t,n){var a={ss:t?"секунда_секунди_секунд":"секунду_секунди_секунд",mm:t?"хвилина_хвилини_хвилин":"хвилину_хвилини_хвилин",hh:t?"година_години_годин":"годину_години_годин",dd:"день_дні_днів",MM:"місяць_місяці_місяців",yy:"рік_роки_років"};if(n==="m")return t?"хвилина":"хвилину";else if(n==="h")return t?"година":"годину";else return e+" "+r(a[n],+e)}function n(e,t){var n={nominative:"неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота".split("_"),accusative:"неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу".split("_"),genitive:"неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи".split("_")},a;if(e===true)return n["nominative"].slice(1,7).concat(n["nominative"].slice(0,1));if(!e)return n["nominative"];a=/(\[[ВвУу]\]) ?dddd/.test(t)?"accusative":/\[?(?:минулої|наступної)? ?\] ?dddd/.test(t)?"genitive":"nominative";return n[a][e.day()]}function a(e){return function(){return e+"о"+(this.hours()===11?"б":"")+"] LT"}}var o;e.defineLocale("uk",{months:{format:"січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня".split("_"),standalone:"січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень".split("_")},monthsShort:"січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд".split("_"),weekdays:n,weekdaysShort:"нд_пн_вт_ср_чт_пт_сб".split("_"),weekdaysMin:"нд_пн_вт_ср_чт_пт_сб".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"D MMMM YYYY р.",LLL:"D MMMM YYYY р., HH:mm",LLLL:"dddd, D MMMM YYYY р., HH:mm"},calendar:{sameDay:a("[Сьогодні "),nextDay:a("[Завтра "),lastDay:a("[Вчора "),nextWeek:a("[У] dddd ["),lastWeek:function(){switch(this.day()){case 0:case 3:case 5:case 6:return a("[Минулої] dddd [").call(this);case 1:case 2:case 4:return a("[Минулого] dddd [").call(this)}},sameElse:"L"},relativeTime:{future:"за %s",past:"%s тому",s:"декілька секунд",ss:t,m:t,mm:t,h:"годину",hh:t,d:"день",dd:t,M:"місяць",MM:t,y:"рік",yy:t},meridiemParse:/ночі|ранку|дня|вечора/,isPM:function(e){return/^(дня|вечора)$/.test(e)},meridiem:function(e,t,n){if(e<4)return"ночі";else if(e<12)return"ранку";else if(e<17)return"дня";else return"вечора"},dayOfMonthOrdinalParse:/\d{1,2}-(й|го)/,ordinal:function(e,t){switch(t){case"M":case"d":case"DDD":case"w":case"W":return e+"-й";case"D":return e+"-го";default:return e}},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t=["جنوری","فروری","مارچ","اپریل","مئی","جون","جولائی","اگست","ستمبر","اکتوبر","نومبر","دسمبر"],n=["اتوار","پیر","منگل","بدھ","جمعرات","جمعہ","ہفتہ"],a;e.defineLocale("ur",{months:t,monthsShort:t,weekdays:n,weekdaysShort:n,weekdaysMin:n,longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd، D MMMM YYYY HH:mm"},meridiemParse:/صبح|شام/,isPM:function(e){return"شام"===e},meridiem:function(e,t,n){if(e<12)return"صبح";return"شام"},calendar:{sameDay:"[آج بوقت] LT",nextDay:"[کل بوقت] LT",nextWeek:"dddd [بوقت] LT",lastDay:"[گذشتہ روز بوقت] LT",lastWeek:"[گذشتہ] dddd [بوقت] LT",sameElse:"L"},relativeTime:{future:"%s بعد",past:"%s قبل",s:"چند سیکنڈ",ss:"%d سیکنڈ",m:"ایک منٹ",mm:"%d منٹ",h:"ایک گھنٹہ",hh:"%d گھنٹے",d:"ایک دن",dd:"%d دن",M:"ایک ماہ",MM:"%d ماہ",y:"ایک سال",yy:"%d سال"},preparse:function(e){return e.replace(/،/g,",")},postformat:function(e){return e.replace(/,/g,"،")},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("uz",{months:"январ_феврал_март_апрел_май_июн_июл_август_сентябр_октябр_ноябр_декабр".split("_"),monthsShort:"янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек".split("_"),weekdays:"Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба".split("_"),weekdaysShort:"Якш_Душ_Сеш_Чор_Пай_Жум_Шан".split("_"),weekdaysMin:"Як_Ду_Се_Чо_Па_Жу_Ша".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Бугун соат] LT [да]",nextDay:"[Эртага] LT [да]",nextWeek:"dddd [куни соат] LT [да]",lastDay:"[Кеча соат] LT [да]",lastWeek:"[Утган] dddd [куни соат] LT [да]",sameElse:"L"},relativeTime:{future:"Якин %s ичида",past:"Бир неча %s олдин",s:"фурсат",ss:"%d фурсат",m:"бир дакика",mm:"%d дакика",h:"бир соат",hh:"%d соат",d:"бир кун",dd:"%d кун",M:"бир ой",MM:"%d ой",y:"бир йил",yy:"%d йил"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("uz-latn",{months:"Yanvar_Fevral_Mart_Aprel_May_Iyun_Iyul_Avgust_Sentabr_Oktabr_Noyabr_Dekabr".split("_"),monthsShort:"Yan_Fev_Mar_Apr_May_Iyun_Iyul_Avg_Sen_Okt_Noy_Dek".split("_"),weekdays:"Yakshanba_Dushanba_Seshanba_Chorshanba_Payshanba_Juma_Shanba".split("_"),weekdaysShort:"Yak_Dush_Sesh_Chor_Pay_Jum_Shan".split("_"),weekdaysMin:"Ya_Du_Se_Cho_Pa_Ju_Sha".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"D MMMM YYYY, dddd HH:mm"},calendar:{sameDay:"[Bugun soat] LT [da]",nextDay:"[Ertaga] LT [da]",nextWeek:"dddd [kuni soat] LT [da]",lastDay:"[Kecha soat] LT [da]",lastWeek:"[O'tgan] dddd [kuni soat] LT [da]",sameElse:"L"},relativeTime:{future:"Yaqin %s ichida",past:"Bir necha %s oldin",s:"soniya",ss:"%d soniya",m:"bir daqiqa",mm:"%d daqiqa",h:"bir soat",hh:"%d soat",d:"bir kun",dd:"%d kun",M:"bir oy",MM:"%d oy",y:"bir yil",yy:"%d yil"},week:{dow:1,doy:7}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("vi",{months:"tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12".split("_"),monthsShort:"Thg 01_Thg 02_Thg 03_Thg 04_Thg 05_Thg 06_Thg 07_Thg 08_Thg 09_Thg 10_Thg 11_Thg 12".split("_"),monthsParseExact:true,weekdays:"chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy".split("_"),weekdaysShort:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysMin:"CN_T2_T3_T4_T5_T6_T7".split("_"),weekdaysParseExact:true,meridiemParse:/sa|ch/i,isPM:function(e){return/^ch$/i.test(e)},meridiem:function(e,t,n){if(e<12)return n?"sa":"SA";else return n?"ch":"CH"},longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"D MMMM [năm] YYYY",LLL:"D MMMM [năm] YYYY HH:mm",LLLL:"dddd, D MMMM [năm] YYYY HH:mm",l:"DD/M/YYYY",ll:"D MMM YYYY",lll:"D MMM YYYY HH:mm",llll:"ddd, D MMM YYYY HH:mm"},calendar:{sameDay:"[Hôm nay lúc] LT",nextDay:"[Ngày mai lúc] LT",nextWeek:"dddd [tuần tới lúc] LT",lastDay:"[Hôm qua lúc] LT",lastWeek:"dddd [tuần trước lúc] LT",sameElse:"L"},relativeTime:{future:"%s tới",past:"%s trước",s:"vài giây",ss:"%d giây",m:"một phút",mm:"%d phút",h:"một giờ",hh:"%d giờ",d:"một ngày",dd:"%d ngày",w:"một tuần",ww:"%d tuần",M:"một tháng",MM:"%d tháng",y:"một năm",yy:"%d năm"},dayOfMonthOrdinalParse:/\d{1,2}/,ordinal:function(e){return e},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("x-pseudo",{months:"J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér".split("_"),monthsShort:"J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc".split("_"),monthsParseExact:true,weekdays:"S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý".split("_"),weekdaysShort:"S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát".split("_"),weekdaysMin:"S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá".split("_"),weekdaysParseExact:true,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~ódá~ý át] LT",nextDay:"[T~ómó~rró~w át] LT",nextWeek:"dddd [át] LT",lastDay:"[Ý~ést~érdá~ý át] LT",lastWeek:"[L~ást] dddd [át] LT",sameElse:"L"},relativeTime:{future:"í~ñ %s",past:"%s á~gó",s:"á ~féw ~sécó~ñds",ss:"%d s~écóñ~ds",m:"á ~míñ~úté",mm:"%d m~íñú~tés",h:"á~ñ hó~úr",hh:"%d h~óúrs",d:"á ~dáý",dd:"%d d~áýs",M:"á ~móñ~th",MM:"%d m~óñt~hs",y:"á ~ýéár",yy:"%d ý~éárs"},dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("yo",{months:"Sẹ́rẹ́_Èrèlè_Ẹrẹ̀nà_Ìgbé_Èbibi_Òkùdu_Agẹmo_Ògún_Owewe_Ọ̀wàrà_Bélú_Ọ̀pẹ̀̀".split("_"),monthsShort:"Sẹ́r_Èrl_Ẹrn_Ìgb_Èbi_Òkù_Agẹ_Ògú_Owe_Ọ̀wà_Bél_Ọ̀pẹ̀̀".split("_"),weekdays:"Àìkú_Ajé_Ìsẹ́gun_Ọjọ́rú_Ọjọ́bọ_Ẹtì_Àbámẹ́ta".split("_"),weekdaysShort:"Àìk_Ajé_Ìsẹ́_Ọjr_Ọjb_Ẹtì_Àbá".split("_"),weekdaysMin:"Àì_Aj_Ìs_Ọr_Ọb_Ẹt_Àb".split("_"),longDateFormat:{LT:"h:mm A",LTS:"h:mm:ss A",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY h:mm A",LLLL:"dddd, D MMMM YYYY h:mm A"},calendar:{sameDay:"[Ònì ni] LT",nextDay:"[Ọ̀la ni] LT",nextWeek:"dddd [Ọsẹ̀ tón'bọ] [ni] LT",lastDay:"[Àna ni] LT",lastWeek:"dddd [Ọsẹ̀ tólọ́] [ni] LT",sameElse:"L"},relativeTime:{future:"ní %s",past:"%s kọjá",s:"ìsẹjú aayá die",ss:"aayá %d",m:"ìsẹjú kan",mm:"ìsẹjú %d",h:"wákati kan",hh:"wákati %d",d:"ọjọ́ kan",dd:"ọjọ́ %d",M:"osù kan",MM:"osù %d",y:"ọdún kan",yy:"ọdún %d"},dayOfMonthOrdinalParse:/ọjọ́\s\d{1,2}/,ordinal:"ọjọ́ %d",week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日Ah点mm分",LLLL:"YYYY年M月D日ddddAh点mm分",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="凌晨"||t==="早上"||t==="上午")return e;else if(t==="下午"||t==="晚上")return e+12;else return e>=11?e:e+12},meridiem:function(e,t,n){var a=e*100+t;if(a<600)return"凌晨";else if(a<900)return"早上";else if(a<1130)return"上午";else if(a<1230)return"中午";else if(a<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:function(e){if(e.week()!==this.week())return"[下]dddLT";else return"[本]dddLT"},lastDay:"[昨天]LT",lastWeek:function(e){if(this.week()!==e.week())return"[上]dddLT";else return"[本]dddLT"},sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|周)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"周";default:return e}},relativeTime:{future:"%s后",past:"%s前",s:"几秒",ss:"%d 秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",w:"1 周",ww:"%d 周",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},week:{dow:1,doy:4}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("zh-hk",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="凌晨"||t==="早上"||t==="上午")return e;else if(t==="中午")return e>=11?e:e+12;else if(t==="下午"||t==="晚上")return e+12},meridiem:function(e,t,n){var a=e*100+t;if(a<600)return"凌晨";else if(a<900)return"早上";else if(a<1200)return"上午";else if(a===1200)return"中午";else if(a<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"幾秒",ss:"%d 秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("zh-mo",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD/MM/YYYY",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"D/M/YYYY",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="凌晨"||t==="早上"||t==="上午")return e;else if(t==="中午")return e>=11?e:e+12;else if(t==="下午"||t==="晚上")return e+12},meridiem:function(e,t,n){var a=e*100+t;if(a<600)return"凌晨";else if(a<900)return"早上";else if(a<1130)return"上午";else if(a<1230)return"中午";else if(a<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天] LT",nextDay:"[明天] LT",nextWeek:"[下]dddd LT",lastDay:"[昨天] LT",lastWeek:"[上]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",ss:"%d 秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}})}(n(9))},function(e,t,n){!function(e){"use strict"; +//! moment.js locale configuration +var t;e.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY年M月D日",LLL:"YYYY年M月D日 HH:mm",LLLL:"YYYY年M月D日dddd HH:mm",l:"YYYY/M/D",ll:"YYYY年M月D日",lll:"YYYY年M月D日 HH:mm",llll:"YYYY年M月D日dddd HH:mm"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(e,t){if(e===12)e=0;if(t==="凌晨"||t==="早上"||t==="上午")return e;else if(t==="中午")return e>=11?e:e+12;else if(t==="下午"||t==="晚上")return e+12},meridiem:function(e,t,n){var a=e*100+t;if(a<600)return"凌晨";else if(a<900)return"早上";else if(a<1130)return"上午";else if(a<1230)return"中午";else if(a<1800)return"下午";else return"晚上"},calendar:{sameDay:"[今天] LT",nextDay:"[明天] LT",nextWeek:"[下]dddd LT",lastDay:"[昨天] LT",lastWeek:"[上]dddd LT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(日|月|週)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"日";case"M":return e+"月";case"w":case"W":return e+"週";default:return e}},relativeTime:{future:"%s後",past:"%s前",s:"幾秒",ss:"%d 秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}})}(n(9))},function(e,t,n){"use strict";t.__esModule=!0;var u=p(n(3)),a=p(n(4)),r=p(n(7)),o=p(n(8)),i=n(0),c=p(i),s=p(n(5)),d=p(n(18)),l=p(n(6)),f=n(11);function p(e){return e&&e.__esModule?e:{default:e}}h=i.Component,(0,o.default)(m,h),m.prototype.render=function(){var e,t=this.props,n=t.prefix,a=t.type,r=t.size,o=t.className,i=t.rtl,s=t.style,t=t.children,l=f.obj.pickOthers((0,u.default)({},m.propTypes),this.props),n=(0,d.default)(((e={})[n+"icon"]=!0,e[n+"icon-"+a]=!!a,e[""+n+r]=!!r&&"string"==typeof r,e[o]=!!o,e)),o=(i&&-1!==["arrow-left","arrow-right","arrow-double-left","arrow-double-right","switch","sorting","descending","ascending"].indexOf(a)&&(l.dir="rtl"),"number"==typeof r?{width:r,height:r,lineHeight:r+"px",fontSize:r}:{});return c.default.createElement("i",(0,u.default)({},l,{style:(0,u.default)({},o,s),className:n}),t)},i=n=m,n.propTypes=(0,u.default)({},l.default.propTypes,{type:s.default.string,children:s.default.node,size:s.default.oneOfType([s.default.oneOf(["xxs","xs","small","medium","large","xl","xxl","xxxl","inherit"]),s.default.number]),className:s.default.string,style:s.default.object}),n.defaultProps={prefix:"next-",size:"medium"},n._typeMark="icon";var h,o=i;function m(){return(0,a.default)(this,m),(0,r.default)(this,h.apply(this,arguments))}o.displayName="Icon",t.default=o,e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0;var g=l(n(3)),y=l(n(16)),a=l(n(42)),r=l(n(4)),o=l(n(7)),i=l(n(8)),v=n(0),_=l(v),s=l(n(5)),b=n(166),w=l(n(544));function l(e){return e&&e.__esModule?e:{default:e}}function u(){}function M(e){return _.default.Children.toArray(e.children)[0]||null}c=v.Component,(0,i.default)(d,c),d.prototype.normalizeNames=function(e){return"string"==typeof e?{appear:e+"-appear",appearActive:e+"-appear-active",enter:e+"-enter",enterActive:e+"-enter-active",leave:e+"-leave",leaveActive:e+"-leave-active"}:"object"===(void 0===e?"undefined":(0,a.default)(e))?{appear:e.appear,appearActive:e.appear+"-active",enter:""+e.enter,enterActive:e.enter+"-active",leave:""+e.leave,leaveActive:e.leave+"-active"}:void 0},d.prototype.render=function(){var t=this,e=this.props,n=e.animation,a=e.children,r=e.animationAppear,o=e.singleMode,i=e.component,s=e.beforeAppear,l=e.onAppear,u=e.afterAppear,c=e.beforeEnter,d=e.onEnter,f=e.afterEnter,p=e.beforeLeave,h=e.onLeave,m=e.afterLeave,e=(0,y.default)(e,["animation","children","animationAppear","singleMode","component","beforeAppear","onAppear","afterAppear","beforeEnter","onEnter","afterEnter","beforeLeave","onLeave","afterLeave"]),a=v.Children.map(a,function(e){return _.default.createElement(w.default,{key:e.key,names:t.normalizeNames(n),onAppear:s,onAppearing:l,onAppeared:u,onEnter:c,onEntering:d,onEntered:f,onExit:p,onExiting:h,onExited:m},e)});return _.default.createElement(b.TransitionGroup,(0,g.default)({appear:r,component:o?M:i},e),a)},i=n=d,n.propTypes={animation:s.default.oneOfType([s.default.string,s.default.object]),animationAppear:s.default.bool,component:s.default.any,singleMode:s.default.bool,children:s.default.oneOfType([s.default.element,s.default.arrayOf(s.default.element)]),beforeAppear:s.default.func,onAppear:s.default.func,afterAppear:s.default.func,beforeEnter:s.default.func,onEnter:s.default.func,afterEnter:s.default.func,beforeLeave:s.default.func,onLeave:s.default.func,afterLeave:s.default.func},n.defaultProps={animationAppear:!0,component:"div",singleMode:!0,beforeAppear:u,onAppear:u,afterAppear:u,beforeEnter:u,onEnter:u,afterEnter:u,beforeLeave:u,onLeave:u,afterLeave:u};var c,s=i;function d(){return(0,r.default)(this,d),(0,o.default)(this,c.apply(this,arguments))}s.displayName="Animate",t.default=s,e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0,t.default=t.EXITING=t.ENTERED=t.ENTERING=t.EXITED=t.UNMOUNTED=void 0;var a=function(e){{if(e&&e.__esModule)return e;var t,n={};if(null!=e)for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&((t=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(e,a):{}).get||t.set?Object.defineProperty(n,a,t):n[a]=e[a]);return n.default=e,n}}(n(5)),o=s(n(0)),i=s(n(24)),r=n(30);n(360);function s(e){return e&&e.__esModule?e:{default:e}}var l="unmounted",u=(t.UNMOUNTED=l,"exited"),c=(t.EXITED=u,"entering"),d=(t.ENTERING=c,"entered"),f=(t.ENTERED=d,"exiting"),n=(t.EXITING=f,function(r){var e;function t(e,t){var n,a=r.call(this,e,t)||this,t=t.transitionGroup,t=t&&!t.isMounting?e.enter:e.appear;return a.appearStatus=null,e.in?t?(n=u,a.appearStatus=c):n=d:n=e.unmountOnExit||e.mountOnEnter?l:u,a.state={status:n},a.nextCallback=null,a}e=r,(n=t).prototype=Object.create(e.prototype),(n.prototype.constructor=n).__proto__=e;var n=t.prototype;return n.getChildContext=function(){return{transitionGroup:null}},t.getDerivedStateFromProps=function(e,t){return e.in&&t.status===l?{status:u}:null},n.componentDidMount=function(){this.updateStatus(!0,this.appearStatus)},n.componentDidUpdate=function(e){var t=null;e!==this.props&&(e=this.state.status,this.props.in?e!==c&&e!==d&&(t=c):e!==c&&e!==d||(t=f)),this.updateStatus(!1,t)},n.componentWillUnmount=function(){this.cancelNextCallback()},n.getTimeouts=function(){var e,t,n=this.props.timeout,a=e=t=n;return null!=n&&"number"!=typeof n&&(a=n.exit,e=n.enter,t=void 0!==n.appear?n.appear:e),{exit:a,enter:e,appear:t}},n.updateStatus=function(e,t){var n;void 0===e&&(e=!1),null!==t?(this.cancelNextCallback(),n=i.default.findDOMNode(this),t===c?this.performEnter(n,e):this.performExit(n)):this.props.unmountOnExit&&this.state.status===u&&this.setState({status:l})},n.performEnter=function(e,t){var n=this,a=this.props.enter,r=this.context.transitionGroup?this.context.transitionGroup.isMounting:t,o=this.getTimeouts(),i=r?o.appear:o.enter;t||a?(this.props.onEnter(e,r),this.safeSetState({status:c},function(){n.props.onEntering(e,r),n.onTransitionEnd(e,i,function(){n.safeSetState({status:d},function(){n.props.onEntered(e,r)})})})):this.safeSetState({status:d},function(){n.props.onEntered(e)})},n.performExit=function(e){var t=this,n=this.props.exit,a=this.getTimeouts();n?(this.props.onExit(e),this.safeSetState({status:f},function(){t.props.onExiting(e),t.onTransitionEnd(e,a.exit,function(){t.safeSetState({status:u},function(){t.props.onExited(e)})})})):this.safeSetState({status:u},function(){t.props.onExited(e)})},n.cancelNextCallback=function(){null!==this.nextCallback&&(this.nextCallback.cancel(),this.nextCallback=null)},n.safeSetState=function(e,t){t=this.setNextCallback(t),this.setState(e,t)},n.setNextCallback=function(t){var n=this,a=!0;return this.nextCallback=function(e){a&&(a=!1,n.nextCallback=null,t(e))},this.nextCallback.cancel=function(){a=!1},this.nextCallback},n.onTransitionEnd=function(e,t,n){this.setNextCallback(n);n=null==t&&!this.props.addEndListener;!e||n?setTimeout(this.nextCallback,0):(this.props.addEndListener&&this.props.addEndListener(e,this.nextCallback),null!=t&&setTimeout(this.nextCallback,t))},n.render=function(){var e,t,n=this.state.status;return n===l?null:(e=(t=this.props).children,delete(t=function(e,t){if(null==e)return{};for(var n,a={},r=Object.keys(e),o=0;o 16.8.0"),null)},e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0;var L=l(n(3)),a=l(n(4)),r=l(n(7)),o=l(n(8)),p=n(0),O=l(p),i=l(n(5)),D=l(n(18)),h=l(n(26)),N=n(11),s=l(n(374)),P=l(n(375));function l(e){return e&&e.__esModule?e:{default:e}}function m(e){e.preventDefault()}u=s.default,(0,o.default)(j,u),j.prototype.getValueLength=function(e){var e=""+e,t=this.props.getValueLength(e);return t="number"!=typeof t?e.length:t},j.prototype.renderControl=function(){var e=this,t=this.props,n=t.hasClear,a=t.readOnly,r=t.state,o=t.prefix,i=t.hint,s=t.extra,l=t.locale,u=t.disabled,t=t.hoverShowClear,c=this.renderLength(),d=null,f=("success"===r?d=O.default.createElement(h.default,{type:"success-filling",className:o+"input-success-icon"}):"loading"===r?d=O.default.createElement(h.default,{type:"loading",className:o+"input-loading-icon"}):"warning"===r&&(d=O.default.createElement(h.default,{type:"warning",className:o+"input-warning-icon"})),null),a=n&&!a&&!!(""+this.state.value)&&!u;return(i||a)&&(u=null,u=i?"string"==typeof i?O.default.createElement(h.default,{type:i,className:o+"input-hint"}):(0,p.isValidElement)(i)?(0,p.cloneElement)(i,{className:(0,D.default)(i.props.className,o+"input-hint")}):i:(t=(0,D.default)(((a={})[o+"input-hint"]=!0,a[o+"input-clear-icon"]=!0,a[o+"input-hover-show"]=t,a)),O.default.createElement(h.default,{type:"delete-filling",role:"button",tabIndex:"0",className:t,"aria-label":l.clear,onClick:this.onClear.bind(this),onMouseDown:m,onKeyDown:this.handleKeyDownFromClear})),f=O.default.createElement("span",{className:o+"input-hint-wrap"},n&&i?O.default.createElement(h.default,{type:"delete-filling",role:"button",tabIndex:"0",className:o+"input-clear "+o+"input-clear-icon","aria-label":l.clear,onClick:this.onClear.bind(this),onMouseDown:m,onKeyDown:this.handleKeyDownFromClear}):null,u)),(f="loading"===r?null:f)||c||d||s?O.default.createElement("span",{onClick:function(){return e.focus()},className:o+"input-control"},f,c,d,s):null},j.prototype.renderLabel=function(){var e=this.props,t=e.label,n=e.prefix,e=e.id;return t?O.default.createElement("label",{className:n+"input-label",htmlFor:e},t):null},j.prototype.renderInner=function(e,t){return e?O.default.createElement("span",{className:t},e):null},j.prototype.onClear=function(e){this.props.disabled||("value"in this.props||this.setState({value:""}),this.props.onChange("",e,"clear"),this.focus())},j.prototype.render=function(){var e,t=this.props,n=t.size,a=t.htmlType,r=t.htmlSize,o=t.autoComplete,i=t.autoFocus,s=t.disabled,l=t.style,u=t.innerBefore,c=t.innerAfter,d=t.innerBeforeClassName,f=t.innerAfterClassName,p=t.className,h=t.hasBorder,m=t.prefix,g=t.isPreview,y=t.renderPreview,v=t.addonBefore,_=t.addonAfter,b=t.addonTextBefore,w=t.addonTextAfter,M=t.inputRender,k=t.rtl,t=t.composition,S=v||_||b||w,h=(0,D.default)(this.getClass(),((E={})[""+m+n]=!0,E[m+"hidden"]="hidden"===this.props.htmlType,E[m+"noborder"]=!h||"file"===this.props.htmlType,E[m+"input-group-auto-width"]=S,E[m+"disabled"]=s,E[p]=!!p&&!S,E)),E=m+"input-inner",d=(0,D.default)(((x={})[E]=!0,x[m+"before"]=!0,x[d]=d,x)),E=(0,D.default)(((x={})[E]=!0,x[m+"after"]=!0,x[m+"input-inner-text"]="string"==typeof c,x[f]=f,x)),x=(0,D.default)(((f={})[m+"form-preview"]=!0,f[p]=!!p,f)),f=this.getProps(),C=N.obj.pickAttrsWith(this.props,"data-"),T=N.obj.pickOthers((0,L.default)({},C,j.propTypes),this.props);return g?(g=f.value,e=this.props.label,"function"==typeof y?O.default.createElement("div",(0,L.default)({},T,{className:x}),y(g,this.props)):O.default.createElement("div",(0,L.default)({},T,{className:x}),v||b,e,u,g,c,_||w)):(y={},t&&(y.onCompositionStart=this.handleCompositionStart,y.onCompositionEnd=this.handleCompositionEnd),x=O.default.createElement("input",(0,L.default)({},T,f,y,{height:"100%",type:a,size:r,autoFocus:i,autoComplete:o,onKeyDown:this.handleKeyDown,ref:this.saveRef})),e=O.default.createElement("span",(0,L.default)({},C,{dir:k?"rtl":void 0,className:h,style:S?void 0:l}),this.renderLabel(),this.renderInner(u,d),M(x),this.renderInner(c,E),this.renderControl()),t=(0,D.default)(((g={})[m+"input-group-text"]=!0,g[""+m+n]=!!n,g[m+"disabled"]=s,g)),f=(0,D.default)(((T={})[t]=b,T)),a=(0,D.default)(((y={})[t]=w,y)),S?O.default.createElement(P.default,(0,L.default)({},C,{prefix:m,className:p,style:l,disabled:s,addonBefore:v||b,addonBeforeClassName:f,addonAfter:_||w,addonAfterClassName:a}),e):e)},o=n=j,n.displayName="Input",n.getDerivedStateFromProps=s.default.getDerivedStateFromProps,n.propTypes=(0,L.default)({},s.default.propTypes,{label:i.default.node,hasClear:i.default.bool,hasBorder:i.default.bool,state:i.default.oneOf(["error","loading","success","warning"]),onPressEnter:i.default.func,htmlType:i.default.string,htmlSize:i.default.string,hint:i.default.oneOfType([i.default.string,i.default.node]),innerBefore:i.default.node,innerAfter:i.default.node,addonBefore:i.default.node,addonAfter:i.default.node,addonTextBefore:i.default.node,addonTextAfter:i.default.node,autoComplete:i.default.string,autoFocus:i.default.bool,inputRender:i.default.func,extra:i.default.node,innerBeforeClassName:i.default.string,innerAfterClassName:i.default.string,isPreview:i.default.bool,renderPreview:i.default.func,hoverShowClear:i.default.bool}),n.defaultProps=(0,L.default)({},s.default.defaultProps,{autoComplete:"off",hasBorder:!0,isPreview:!1,hoverShowClear:!1,onPressEnter:N.func.noop,inputRender:function(e){return e}});var u,i=o;function j(e){(0,a.default)(this,j);var t=(0,r.default)(this,u.call(this,e)),n=(t.handleKeyDown=function(e){13===e.keyCode&&t.props.onPressEnter(e),t.onKeyDown(e)},t.handleKeyDownFromClear=function(e){13===e.keyCode&&t.onClear(e)},void 0),n="value"in e?e.value:e.defaultValue;return t.state={value:void 0===n?"":n},t}t.default=i,e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0;var a,r=h(n(3)),o=h(n(4)),i=h(n(7)),s=h(n(8)),l=h(n(0)),u=h(n(5)),c=h(n(18)),d=n(30),f=h(n(6)),p=n(11),n=h(n(44));function h(e){return e&&e.__esModule?e:{default:e}}m=l.default.Component,(0,s.default)(g,m),g.getDerivedStateFromProps=function(e,t){return"value"in e&&e.value!==t.value&&!t.composition?{value:null==(t=e.value)?"":t}:null},g.prototype.ieHack=function(e){return e},g.prototype.onChange=function(e){"stopPropagation"in e?e.stopPropagation():"cancelBubble"in e&&e.cancelBubble();var t=e.target.value;this.props.trim&&(t=t.trim()),t=this.ieHack(t),"value"in this.props&&!this.state.composition||this.setState({value:t}),this.state.composition||(t&&"number"===this.props.htmlType&&(t=Number(t)),this.props.onChange(t,e))},g.prototype.onKeyDown=function(e){var t=e.target.value,n=this.props.maxLength,t=0>6]+c[128|63&l]:l<55296||57344<=l?i+=c[224|l>>12]+c[128|l>>6&63]+c[128|63&l]:(s+=1,l=65536+((1023&l)<<10|1023&o.charCodeAt(s)),i+=c[240|l>>18]+c[128|l>>12&63]+c[128|l>>6&63]+c[128|63&l])}return i},isBuffer:function(e){return!(!e||"object"!=typeof e||!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e)))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(m(e)){for(var n=[],a=0;athis.popupNode.offsetWidth&&p(this.popupNode,"width",s.offsetWidth+"px"),"outside"!==a||"hoz"===r&&1===n||(p(this.popupNode,"height",u.offsetHeight+"px"),this.popupNode.firstElementChild&&p(this.popupNode.firstElementChild,"overflow-y","auto")),this.popupProps);c.onOpen&&c.onOpen()}catch(e){return null}},S.prototype.handlePopupClose=function(){var e=this.props.root.popupNodes,t=e.indexOf(this.popupNode),e=(-1t?r[t+1]:r[0])}),n[a]||(o=r[0]),i.onSort(a,o)},i.keydownHandler=function(e){e.preventDefault(),e.stopPropagation(),e.keyCode===s.KEYCODE.ENTER&&i.handleClick()},i.onSort=function(e,t){var n={};i.props.onSort(e,n[e]=t,n)},(0,o.default)(i,e)}i.displayName="Sort",t.default=i,e.exports=t.default},function(e,t,n){"use strict";t.__esModule=!0,t.default=void 0;var r=d(n(3)),a=d(n(4)),o=d(n(7)),i=d(n(8)),s=d(n(0)),l=d(n(5)),u=d(n(18)),c=d(n(405));function d(e){return e&&e.__esModule?e:{default:e}}f=s.default.Component,(0,i.default)(p,f),p.prototype.render=function(){var e=this.props,t=e.className,n=e.record,e=e.primaryKey,a=this.context.selectedRowKeys,n=(0,u.default)(((a={selected:-1t.highWaterMark&&(t.highWaterMark=(p<=(n=e)?n=p:(n--,n=(n=(n=(n=(n|=n>>>1)|n>>>2)|n>>>4)|n>>>8)|n>>>16,n++),n)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function b(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(_("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?y.nextTick(w,e):w(e))}function w(e){_("emit readable"),e.emit("readable"),x(e)}function M(e,t){t.readingMore||(t.readingMore=!0,y.nextTick(k,e,t))}function k(e,t){for(var n=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(n=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):n=function(e,t,n){var a;eo.length?o.length:e;if(i===o.length?r+=o:r+=o.slice(0,e),0===(e-=i)){i===o.length?(++a,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n).data=o.slice(i);break}++a}return t.length-=a,r}:function(e,t){var n=c.allocUnsafe(e),a=t.head,r=1;a.data.copy(n),e-=a.data.length;for(;a=a.next;){var o=a.data,i=e>o.length?o.length:e;if(o.copy(n,n.length-e,0,i),0===(e-=i)){i===o.length?(++r,a.next?t.head=a.next:t.head=t.tail=null):(t.head=a).data=o.slice(i);break}++r}return t.length-=r,n})(e,t);return a}(e,t.buffer,t.decoder),n)}function T(e){var t=e._readableState;if(0=n.highWaterMark||n.ended)?(_("read: emitReadable",n.length,n.ended),(0===n.length&&n.ended?T:b)(this),null):0===(e=h(e,n))&&n.ended?(0===n.length&&T(this),null):(t=n.needReadable,_("need readable",t),(0===n.length||n.length-e + * @license MIT + */ +var S=P(706),o=P(707),s=P(708);function n(){return d.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function l(e,t){if(n()=n())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+n().toString(16)+" bytes");return 0|e}function f(e,t){if(d.isBuffer(e))return e.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e.byteLength;var n=(e="string"!=typeof e?""+e:e).length;if(0===n)return 0;for(var a=!1;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return L(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return O(e).length;default:if(a)return L(e).length;t=(""+t).toLowerCase(),a=!0}}function t(e,t,n){var a,r=!1;if((t=void 0===t||t<0?0:t)>this.length)return"";if((n=void 0===n||n>this.length?this.length:n)<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e=e||"utf8";;)switch(e){case"hex":var o=this,i=t,s=n,l=o.length;(!s||s<0||l=e.length){if(r)return-1;n=e.length-1}else if(n<0){if(!r)return-1;n=0}if("string"==typeof t&&(t=d.from(t,a)),d.isBuffer(t))return 0===t.length?-1:m(e,t,n,a,r);if("number"==typeof t)return t&=255,d.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?(r?Uint8Array.prototype.indexOf:Uint8Array.prototype.lastIndexOf).call(e,t,n):m(e,[t],n,a,r);throw new TypeError("val must be string, number or Buffer")}function m(e,t,n,a,r){var o=1,i=e.length,s=t.length;if(void 0!==a&&("ucs2"===(a=String(a).toLowerCase())||"ucs-2"===a||"utf16le"===a||"utf-16le"===a)){if(e.length<2||t.length<2)return-1;i/=o=2,s/=2,n/=2}function l(e,t){return 1===o?e[t]:e.readUInt16BE(t*o)}if(r)for(var u=-1,c=n;c>8,r.push(n%256),r.push(a);return r}(t,e.length-n),e,n,a)}function E(e,t,n){n=Math.min(e.length,n);for(var a=[],r=t;r>>10&1023|55296),c=56320|1023&c),a.push(c),r+=d}var f=a,p=f.length;if(p<=v)return String.fromCharCode.apply(String,f);for(var h="",m=0;mt)&&(e+=" ... "),""},d.prototype.compare=function(e,t,n,a,r){if(!d.isBuffer(e))throw new TypeError("Argument must be a Buffer");if(void 0===n&&(n=e?e.length:0),void 0===a&&(a=0),void 0===r&&(r=this.length),(t=void 0===t?0:t)<0||n>e.length||a<0||r>this.length)throw new RangeError("out of range index");if(r<=a&&n<=t)return 0;if(r<=a)return-1;if(n<=t)return 1;if(this===e)return 0;for(var o=(r>>>=0)-(a>>>=0),i=(n>>>=0)-(t>>>=0),s=Math.min(o,i),l=this.slice(a,r),u=e.slice(t,n),c=0;cthis.length)throw new RangeError("Attempt to write outside buffer bounds");a=a||"utf8";for(var o,i,s,l=!1;;)switch(a){case"hex":var u=this,c=e,d=t,f=n,p=(d=Number(d)||0,u.length-d);if((!f||p<(f=Number(f)))&&(f=p),(p=c.length)%2!=0)throw new TypeError("Invalid hex string");p/2e.length)throw new RangeError("Index out of range")}function w(e,t,n,a){t<0&&(t=65535+t+1);for(var r=0,o=Math.min(e.length-n,2);r>>8*(a?r:1-r)}function M(e,t,n,a){t<0&&(t=4294967295+t+1);for(var r=0,o=Math.min(e.length-n,4);r>>8*(a?r:3-r)&255}function k(e,t,n,a){if(n+a>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function x(e,t,n,a,r){return r||k(e,0,n,4),o.write(e,t,n,a,23,4),n+4}function C(e,t,n,a,r){return r||k(e,0,n,8),o.write(e,t,n,a,52,8),n+8}d.prototype.slice=function(e,t){var n=this.length;if((e=~~e)<0?(e+=n)<0&&(e=0):n>>8):w(this,e,t,!0),t+2},d.prototype.writeUInt16BE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,2,65535,0),d.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):w(this,e,t,!1),t+2},d.prototype.writeUInt32LE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,4,4294967295,0),d.TYPED_ARRAY_SUPPORT?(this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e):M(this,e,t,!0),t+4},d.prototype.writeUInt32BE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,4,4294967295,0),d.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},d.prototype.writeIntLE=function(e,t,n,a){e=+e,t|=0,a||b(this,e,t,n,(a=Math.pow(2,8*n-1))-1,-a);var r=0,o=1,i=0;for(this[t]=255&e;++r>0)-i&255;return t+n},d.prototype.writeIntBE=function(e,t,n,a){e=+e,t|=0,a||b(this,e,t,n,(a=Math.pow(2,8*n-1))-1,-a);var r=n-1,o=1,i=0;for(this[t+r]=255&e;0<=--r&&(o*=256);)e<0&&0===i&&0!==this[t+r+1]&&(i=1),this[t+r]=(e/o>>0)-i&255;return t+n},d.prototype.writeInt8=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,1,127,-128),d.TYPED_ARRAY_SUPPORT||(e=Math.floor(e)),this[t]=255&(e=e<0?255+e+1:e),t+1},d.prototype.writeInt16LE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,2,32767,-32768),d.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8):w(this,e,t,!0),t+2},d.prototype.writeInt16BE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,2,32767,-32768),d.TYPED_ARRAY_SUPPORT?(this[t]=e>>>8,this[t+1]=255&e):w(this,e,t,!1),t+2},d.prototype.writeInt32LE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,4,2147483647,-2147483648),d.TYPED_ARRAY_SUPPORT?(this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24):M(this,e,t,!0),t+4},d.prototype.writeInt32BE=function(e,t,n){return e=+e,t|=0,n||b(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),d.TYPED_ARRAY_SUPPORT?(this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e):M(this,e,t,!1),t+4},d.prototype.writeFloatLE=function(e,t,n){return x(this,e,t,!0,n)},d.prototype.writeFloatBE=function(e,t,n){return x(this,e,t,!1,n)},d.prototype.writeDoubleLE=function(e,t,n){return C(this,e,t,!0,n)},d.prototype.writeDoubleBE=function(e,t,n){return C(this,e,t,!1,n)},d.prototype.copy=function(e,t,n,a){if(n=n||0,a||0===a||(a=this.length),t>=e.length&&(t=e.length),(a=0=this.length)throw new RangeError("sourceStart out of bounds");if(a<0)throw new RangeError("sourceEnd out of bounds");a>this.length&&(a=this.length);var r,o=(a=e.length-t>>=0,n=void 0===n?this.length:n>>>0,"number"==typeof(e=e||0))for(s=t;s>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function O(e){return S.toByteArray(function(e){var t;if((e=((t=e).trim?t.trim():t.replace(/^\s+|\s+$/g,"")).replace(T,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function D(e,t,n,a){for(var r=0;r=t.length||r>=e.length);++r)t[r+n]=e[r];return r}}.call(this,P(65))},function(e,t,n){"use strict";var o=n(138);function i(e,t){e.emit("error",t)}e.exports={destroy:function(e,t){var n=this,a=this._readableState&&this._readableState.destroyed,r=this._writableState&&this._writableState.destroyed;return a||r?t?t(e):e&&(this._writableState?this._writableState.errorEmitted||(this._writableState.errorEmitted=!0,o.nextTick(i,this,e)):o.nextTick(i,this,e)):(this._readableState&&(this._readableState.destroyed=!0),this._writableState&&(this._writableState.destroyed=!0),this._destroy(e||null,function(e){!t&&e?n._writableState?n._writableState.errorEmitted||(n._writableState.errorEmitted=!0,o.nextTick(i,n,e)):o.nextTick(i,n,e):t&&t(e)})),this},undestroy:function(){this._readableState&&(this._readableState.destroyed=!1,this._readableState.reading=!1,this._readableState.ended=!1,this._readableState.endEmitted=!1),this._writableState&&(this._writableState.destroyed=!1,this._writableState.ended=!1,this._writableState.ending=!1,this._writableState.finalCalled=!1,this._writableState.prefinished=!1,this._writableState.finished=!1,this._writableState.errorEmitted=!1)}}},function(e,t,n){"use strict";var a=n(139).Buffer,r=a.isEncoding||function(e){switch((e=""+e)&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};function o(e){var t=function(e){if(!e)return"utf8";for(var t;;)switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase(),t=!0}}(e);if("string"==typeof t||a.isEncoding!==r&&r(e))return t||e;throw new Error("Unknown encoding: "+e)}function i(e){var t;switch(this.encoding=o(e),this.encoding){case"utf16le":this.text=u,this.end=c,t=4;break;case"utf8":this.fillLast=l,t=4;break;case"base64":this.text=d,this.end=f,t=3;break;default:return this.write=p,void(this.end=h)}this.lastNeed=0,this.lastTotal=0,this.lastChar=a.allocUnsafe(t)}function s(e){return e<=127?0:e>>5==6?2:e>>4==14?3:e>>3==30?4:e>>6==2?-1:-2}function l(e){var t,n=this.lastTotal-this.lastNeed,a=(t=this,128!=(192&(a=e)[0])?(t.lastNeed=0,"�"):1e.slidesToShow&&(n=e.slideWidth*e.slidesToShow*-1,o=e.slideHeight*e.slidesToShow*-1),e.slideCount%e.slidesToScroll!=0&&(t=e.slideIndex+e.slidesToScroll>e.slideCount&&e.slideCount>e.slidesToShow,t=e.rtl?(e.slideIndex>=e.slideCount?e.slideCount-e.slideIndex:e.slideIndex)+e.slidesToScroll>e.slideCount&&e.slideCount>e.slidesToShow:t)&&(o=e.slideIndex>e.slideCount?(n=(e.slidesToShow-(e.slideIndex-e.slideCount))*e.slideWidth*-1,(e.slidesToShow-(e.slideIndex-e.slideCount))*e.slideHeight*-1):(n=e.slideCount%e.slidesToScroll*e.slideWidth*-1,e.slideCount%e.slidesToScroll*e.slideHeight*-1))):e.slideCount%e.slidesToScroll!=0&&e.slideIndex+e.slidesToScroll>e.slideCount&&e.slideCount>e.slidesToShow&&(n=(e.slidesToShow-e.slideCount%e.slidesToScroll)*e.slideWidth),e.centerMode&&(e.infinite?n+=e.slideWidth*Math.floor(e.slidesToShow/2):n=e.slideWidth*Math.floor(e.slidesToShow/2)),a=e.vertical?e.slideIndex*e.slideHeight*-1+o:e.slideIndex*e.slideWidth*-1+n,!0===e.variableWidth&&(t=void 0,a=(r=e.slideCount<=e.slidesToShow||!1===e.infinite?i.default.findDOMNode(e.trackRef).childNodes[e.slideIndex]:(t=e.slideIndex+e.slidesToShow,i.default.findDOMNode(e.trackRef).childNodes[t]))?-1*r.offsetLeft:0,!0===e.centerMode)&&(r=!1===e.infinite?i.default.findDOMNode(e.trackRef).children[e.slideIndex]:i.default.findDOMNode(e.trackRef).children[e.slideIndex+e.slidesToShow+1])?-1*r.offsetLeft+(e.listWidth-r.offsetWidth)/2:a)}},function(e,t,n){"use strict";t.__esModule=!0;var p=u(n(3)),h=u(n(16)),o=u(n(4)),i=u(n(7)),a=u(n(8)),m=u(n(0)),r=u(n(5)),g=u(n(18)),s=u(n(6)),y=u(n(26)),l=n(11);function u(e){return e&&e.__esModule?e:{default:e}}c=m.default.Component,(0,a.default)(d,c),d.prototype.render=function(){var e=this.props,t=e.title,n=e.children,a=e.className,r=e.isExpanded,o=e.disabled,i=e.style,s=e.prefix,l=e.onClick,u=e.id,e=(0,h.default)(e,["title","children","className","isExpanded","disabled","style","prefix","onClick","id"]),a=(0,g.default)(((c={})[s+"collapse-panel"]=!0,c[s+"collapse-panel-hidden"]=!r,c[s+"collapse-panel-expanded"]=r,c[s+"collapse-panel-disabled"]=o,c[a]=a,c)),c=(0,g.default)(((c={})[s+"collapse-panel-icon"]=!0,c[s+"collapse-panel-icon-expanded"]=r,c)),d=u?u+"-heading":void 0,f=u?u+"-region":void 0;return m.default.createElement("div",(0,p.default)({className:a,style:i,id:u},e),m.default.createElement("div",{id:d,className:s+"collapse-panel-title",onClick:l,onKeyDown:this.onKeyDown,tabIndex:"0","aria-disabled":o,"aria-expanded":r,"aria-controls":f,role:"button"},m.default.createElement(y.default,{type:"arrow-right",className:c,"aria-hidden":"true"}),t),m.default.createElement("div",{className:s+"collapse-panel-content",role:"region",id:f},n))},a=n=d,n.propTypes={prefix:r.default.string,style:r.default.object,children:r.default.any,isExpanded:r.default.bool,disabled:r.default.bool,title:r.default.node,className:r.default.string,onClick:r.default.func,id:r.default.string},n.defaultProps={prefix:"next-",isExpanded:!1,onClick:l.func.noop},n.isNextPanel=!0;var c,r=a;function d(){var e,n;(0,o.default)(this,d);for(var t=arguments.length,a=Array(t),r=0;r\n com.alibaba.nacos\n nacos-client\n ${version}\n \n*/\npackage com.alibaba.nacos.example;\n\nimport java.util.Properties;\nimport java.util.concurrent.Executor;\nimport com.alibaba.nacos.api.NacosFactory;\nimport com.alibaba.nacos.api.config.ConfigService;\nimport com.alibaba.nacos.api.config.listener.Listener;\nimport com.alibaba.nacos.api.exception.NacosException;\n\n/**\n * Config service example\n *\n * @author Nacos\n *\n */\npublic class ConfigExample {\n\n\tpublic static void main(String[] args) throws NacosException, InterruptedException {\n\t\tString serverAddr = "localhost";\n\t\tString dataId = "'.concat(e.dataId,'";\n\t\tString group = "').concat(e.group,'";\n\t\tProperties properties = new Properties();\n\t\tproperties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);\n\t\tConfigService configService = NacosFactory.createConfigService(properties);\n\t\tString content = configService.getConfig(dataId, group, 5000);\n\t\tSystem.out.println(content);\n\t\tconfigService.addListener(dataId, group, new Listener() {\n\t\t\t@Override\n\t\t\tpublic void receiveConfigInfo(String configInfo) {\n\t\t\t\tSystem.out.println("receive:" + configInfo);\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic Executor getExecutor() {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t});\n\n\t\tboolean isPublishOk = configService.publishConfig(dataId, group, "content");\n\t\tSystem.out.println(isPublishOk);\n\n\t\tThread.sleep(3000);\n\t\tcontent = configService.getConfig(dataId, group, 5000);\n\t\tSystem.out.println(content);\n\n\t\tboolean isRemoveOk = configService.removeConfig(dataId, group);\n\t\tSystem.out.println(isRemoveOk);\n\t\tThread.sleep(3000);\n\n\t\tcontent = configService.getConfig(dataId, group, 5000);\n\t\tSystem.out.println(content);\n\t\tThread.sleep(300000);\n\n\t}\n}\n')}},{key:"getNodejsCode",value:function(e){return"TODO"}},{key:"getCppCode",value:function(e){return"TODO"}},{key:"getShellCode",value:function(e){return"TODO"}},{key:"getPythonCode",value:function(e){return'/*\n* Demo for Nacos\n*/\nimport json\nimport socket\n\nimport nacos\n\n\ndef get_host_ip():\n res = socket.gethostbyname(socket.gethostname())\n return res\n\n\ndef load_config(content):\n _config = json.loads(content)\n return _config\n\n\ndef nacos_config_callback(args):\n content = args[\'raw_content\']\n load_config(content)\n\n\nclass NacosClient:\n service_name = None\n service_port = None\n service_group = None\n\n def __init__(self, server_endpoint, namespace_id, username=None, password=None):\n self.client = nacos.NacosClient(server_endpoint,\n namespace=namespace_id,\n username=username,\n password=password)\n self.endpoint = server_endpoint\n self.service_ip = get_host_ip()\n\n def register(self):\n self.client.add_naming_instance(self.service_name,\n self.service_ip,\n self.service_port,\n group_name=self.service_group)\n\n def modify(self, service_name, service_ip=None, service_port=None):\n self.client.modify_naming_instance(service_name,\n service_ip if service_ip else self.service_ip,\n service_port if service_port else self.service_port)\n\n def unregister(self):\n self.client.remove_naming_instance(self.service_name,\n self.service_ip,\n self.service_port)\n\n def set_service(self, service_name, service_ip, service_port, service_group):\n self.service_name = service_name\n self.service_ip = service_ip\n self.service_port = service_port\n self.service_group = service_group\n\n async def beat_callback(self):\n self.client.send_heartbeat(self.service_name,\n self.service_ip,\n self.service_port)\n\n def load_conf(self, data_id, group):\n return self.client.get_config(data_id=data_id, group=group, no_snapshot=True)\n\n def add_conf_watcher(self, data_id, group, callback):\n self.client.add_config_watcher(data_id=data_id, group=group, cb=callback)\n\n\nif __name__ == \'__main__\':\n nacos_config = {\n "nacos_data_id":"test",\n "nacos_server_ip":"127.0.0.1",\n "nacos_namespace":"public",\n "nacos_groupName":"DEFAULT_GROUP",\n "nacos_user":"nacos",\n "nacos_password":"1234567"\n }\n nacos_data_id = nacos_config["nacos_data_id"]\n SERVER_ADDRESSES = nacos_config["nacos_server_ip"]\n NAMESPACE = nacos_config["nacos_namespace"]\n groupName = nacos_config["nacos_groupName"]\n user = nacos_config["nacos_user"]\n password = nacos_config["nacos_password"]\n # todo 将另一个路由对象(通常定义在其他模块或文件中)合并到主应用(app)中。\n # app.include_router(custom_api.router, tags=[\'test\'])\n service_ip = get_host_ip()\n client = NacosClient(SERVER_ADDRESSES, NAMESPACE, user, password)\n client.add_conf_watcher(nacos_data_id, groupName, nacos_config_callback)\n\n # 启动时,强制同步一次配置\n data_stream = client.load_conf(nacos_data_id, groupName)\n json_config = load_config(data_stream)\n'}},{key:"getCSharpCode",value:function(e){return'/*\nDemo for Basic Nacos Opreation\nApp.csproj\n\n\n \n\n*/\n\nusing Microsoft.Extensions.DependencyInjection;\nusing Nacos.V2;\nusing Nacos.V2.DependencyInjection;\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nclass Program\n{\n static async Task Main(string[] args)\n {\n string serverAddr = "http://localhost:8848";\n string dataId = "'.concat(e.dataId,'";\n string group = "').concat(e.group,'";\n\n IServiceCollection services = new ServiceCollection();\n\n services.AddNacosV2Config(x =>\n {\n x.ServerAddresses = new List { serverAddr };\n x.Namespace = "cs-test";\n\n // swich to use http or rpc\n x.ConfigUseRpc = true;\n });\n\n IServiceProvider serviceProvider = services.BuildServiceProvider();\n var configSvc = serviceProvider.GetService();\n\n var content = await configSvc.GetConfig(dataId, group, 3000);\n Console.WriteLine(content);\n\n var listener = new ConfigListener();\n\n await configSvc.AddListener(dataId, group, listener);\n\n var isPublishOk = await configSvc.PublishConfig(dataId, group, "content");\n Console.WriteLine(isPublishOk);\n\n await Task.Delay(3000);\n content = await configSvc.GetConfig(dataId, group, 5000);\n Console.WriteLine(content);\n\n var isRemoveOk = await configSvc.RemoveConfig(dataId, group);\n Console.WriteLine(isRemoveOk);\n await Task.Delay(3000);\n\n content = await configSvc.GetConfig(dataId, group, 5000);\n Console.WriteLine(content);\n await Task.Delay(300000);\n }\n\n internal class ConfigListener : IListener\n {\n public void ReceiveConfigInfo(string configInfo)\n {\n Console.WriteLine("receive:" + configInfo);\n }\n }\n}\n\n/*\nRefer to document: https://github.com/nacos-group/nacos-sdk-csharp/tree/dev/samples/MsConfigApp\nDemo for ASP.NET Core Integration\nMsConfigApp.csproj\n\n\n \n\n*/\n\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.Hosting;\nusing Serilog;\nusing Serilog.Events;\n\npublic class Program\n{\n public static void Main(string[] args)\n {\n Log.Logger = new LoggerConfiguration()\n .Enrich.FromLogContext()\n .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)\n .MinimumLevel.Override("System", LogEventLevel.Warning)\n .MinimumLevel.Debug()\n .WriteTo.Console()\n .CreateLogger();\n\n try\n {\n Log.ForContext().Information("Application starting...");\n CreateHostBuilder(args, Log.Logger).Build().Run();\n }\n catch (System.Exception ex)\n {\n Log.ForContext().Fatal(ex, "Application start-up failed!!");\n }\n finally\n {\n Log.CloseAndFlush();\n }\n }\n\n public static IHostBuilder CreateHostBuilder(string[] args, Serilog.ILogger logger) =>\n Host.CreateDefaultBuilder(args)\n .ConfigureAppConfiguration((context, builder) =>\n {\n var c = builder.Build();\n builder.AddNacosV2Configuration(c.GetSection("NacosConfig"), logAction: x => x.AddSerilog(logger));\n })\n .ConfigureWebHostDefaults(webBuilder =>\n {\n webBuilder.UseStartup().UseUrls("http://*:8787");\n })\n .UseSerilog();\n}\n ')}},{key:"openDialog",value:function(e){var t=this;this.setState({dialogvisible:!0}),this.record=e,setTimeout(function(){t.getData()})}},{key:"closeDialog",value:function(){this.setState({dialogvisible:!1})}},{key:"createCodeMirror",value:function(e,t){var n=this.refs.codepreview;n&&(n.innerHTML="",this.cm=window.CodeMirror(n,{value:t,mode:e,height:400,width:500,lineNumbers:!0,theme:"xq-light",lint:!0,tabMode:"indent",autoMatchParens:!0,textWrapping:!0,gutters:["CodeMirror-lint-markers"],extraKeys:{F1:function(e){e.setOption("fullScreen",!e.getOption("fullScreen"))},Esc:function(e){e.getOption("fullScreen")&&e.setOption("fullScreen",!1)}}}))}},{key:"changeTab",value:function(e,t){var n=this;setTimeout(function(){n[e]=!0,n.createCodeMirror("text/javascript",t)})}},{key:"render",value:function(){var e=this.props.locale,e=void 0===e?{}:e;return x.a.createElement("div",null,x.a.createElement(y.a,{title:e.sampleCode,style:{width:"80%"},visible:this.state.dialogvisible,footer:x.a.createElement("div",null),onClose:this.closeDialog.bind(this)},x.a.createElement("div",{style:{height:500}},x.a.createElement(R.a,{tip:e.loading,style:{width:"100%"},visible:this.state.loading},x.a.createElement(O.a,{shape:"text",style:{height:40,paddingBottom:10}},x.a.createElement(D,{title:"Java",key:1,onClick:this.changeTab.bind(this,"commoneditor1",this.defaultCode)}),x.a.createElement(D,{title:"Spring Boot",key:2,onClick:this.changeTab.bind(this,"commoneditor2",this.sprigboot_code)}),x.a.createElement(D,{title:"Spring Cloud",key:21,onClick:this.changeTab.bind(this,"commoneditor21",this.sprigcloud_code)}),x.a.createElement(D,{title:"Node.js",key:3,onClick:this.changeTab.bind(this,"commoneditor3",this.nodejsCode)}),x.a.createElement(D,{title:"C++",key:4,onClick:this.changeTab.bind(this,"commoneditor4",this.cppCode)}),x.a.createElement(D,{title:"Shell",key:5,onClick:this.changeTab.bind(this,"commoneditor5",this.shellCode)}),x.a.createElement(D,{title:"Python",key:6,onClick:this.changeTab.bind(this,"commoneditor6",this.pythonCode)}),x.a.createElement(D,{title:"C#",key:7,onClick:this.changeTab.bind(this,"commoneditor7",this.csharpCode)})),x.a.createElement("div",{ref:"codepreview"})))))}}]),n}(x.a.Component)).displayName="ShowCodeing",S=S))||S,S=(t(69),t(40)),S=t.n(S),F=(t(756),S.a.Row),N=S.a.Col,z=(0,n.a.config)(((S=function(e){Object(M.a)(n,e);var t=Object(k.a)(n);function n(e){return Object(_.a)(this,n),(e=t.call(this,e)).state={visible:!1,title:"",content:"",isok:!0,dataId:"",group:""},e}return Object(b.a)(n,[{key:"componentDidMount",value:function(){this.initData()}},{key:"initData",value:function(){var e=this.props.locale;this.setState({title:(void 0===e?{}:e).confManagement})}},{key:"openDialog",value:function(e){this.setState({visible:!0,title:e.title,content:e.content,isok:e.isok,dataId:e.dataId,group:e.group,message:e.message})}},{key:"closeDialog",value:function(){this.setState({visible:!1})}},{key:"render",value:function(){var e=this.props.locale,e=void 0===e?{}:e,t=x.a.createElement("div",{style:{textAlign:"right"}},x.a.createElement(c.a,{type:"primary",onClick:this.closeDialog.bind(this)},e.determine));return x.a.createElement("div",null,x.a.createElement(y.a,{visible:this.state.visible,footer:t,style:{width:555},onCancel:this.closeDialog.bind(this),onClose:this.closeDialog.bind(this),title:e.deletetitle},x.a.createElement("div",null,x.a.createElement(F,null,x.a.createElement(N,{span:"4",style:{paddingTop:16}},x.a.createElement(m.a,{type:"".concat(this.state.isok?"success":"delete","-filling"),style:{color:this.state.isok?"green":"red"},size:"xl"})),x.a.createElement(N,{span:"20"},x.a.createElement("div",null,x.a.createElement("h3",null,this.state.isok?e.deletedSuccessfully:e.deleteFailed),x.a.createElement("p",null,x.a.createElement("span",{style:{color:"#999",marginRight:5}},"Data ID"),x.a.createElement("span",{style:{color:"#c7254e"}},this.state.dataId)),x.a.createElement("p",null,x.a.createElement("span",{style:{color:"#999",marginRight:5}},"Group"),x.a.createElement("span",{style:{color:"#c7254e"}},this.state.group)),this.state.isok?"":x.a.createElement("p",{style:{color:"red"}},this.state.message)))))))}}]),n}(x.a.Component)).displayName="DeleteDialog",S=S))||S,S=(t(757),t(436)),W=t.n(S),B=(0,n.a.config)(((S=function(e){Object(M.a)(n,e);var t=Object(k.a)(n);function n(){return Object(_.a)(this,n),t.apply(this,arguments)}return Object(b.a)(n,[{key:"render",value:function(){var e=this.props,t=e.data,t=void 0===t?{}:t,n=e.height,e=e.locale,a=void 0===e?{}:e;return x.a.createElement("div",null,"notice"===t.modeType?x.a.createElement("div",{"data-spm-click":"gostr=/aliyun;locaid=notice"},x.a.createElement(W.a,{style:{marginBottom:1\n com.alibaba.nacos\n nacos-client\n ${latest.version}\n \n*/\npackage com.alibaba.nacos.example;\n\nimport java.util.Properties;\n\nimport com.alibaba.nacos.api.exception.NacosException;\nimport com.alibaba.nacos.api.naming.NamingFactory;\nimport com.alibaba.nacos.api.naming.NamingService;\nimport com.alibaba.nacos.api.naming.listener.Event;\nimport com.alibaba.nacos.api.naming.listener.EventListener;\nimport com.alibaba.nacos.api.naming.listener.NamingEvent;\n\n/**\n * @author nkorange\n */\npublic class NamingExample {\n\n public static void main(String[] args) throws NacosException {\n\n Properties properties = new Properties();\n properties.setProperty("serverAddr", System.getProperty("serverAddr"));\n properties.setProperty("namespace", System.getProperty("namespace"));\n\n NamingService naming = NamingFactory.createNamingService(properties);\n\n naming.registerInstance("'.concat(this.record.name,'", "11.11.11.11", 8888, "TEST1");\n\n naming.registerInstance("').concat(this.record.name,'", "2.2.2.2", 9999, "DEFAULT");\n\n System.out.println(naming.getAllInstances("').concat(this.record.name,'"));\n\n naming.deregisterInstance("').concat(this.record.name,'", "2.2.2.2", 9999, "DEFAULT");\n\n System.out.println(naming.getAllInstances("').concat(this.record.name,'"));\n\n naming.subscribe("').concat(this.record.name,'", new EventListener() {\n @Override\n public void onEvent(Event event) {\n System.out.println(((NamingEvent)event).getServiceName());\n System.out.println(((NamingEvent)event).getInstances());\n }\n });\n }\n}')}},{key:"getSpringCode",value:function(e){return'/* Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-example/nacos-spring-discovery-example\n* pom.xml\n \n com.alibaba.nacos\n nacos-spring-context\n ${latest.version}\n \n*/\n\n// Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-example/nacos-spring-discovery-example/src/main/java/com/alibaba/nacos/example/spring\npackage com.alibaba.nacos.example.spring;\n\nimport com.alibaba.nacos.api.annotation.NacosProperties;\nimport com.alibaba.nacos.spring.context.annotation.discovery.EnableNacosDiscovery;\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\n@EnableNacosDiscovery(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))\npublic class NacosConfiguration {\n\n}\n\n// Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-example/nacos-spring-discovery-example/src/main/java/com/alibaba/nacos/example/spring/controller\npackage com.alibaba.nacos.example.spring.controller;\n\nimport com.alibaba.nacos.api.annotation.NacosInjected;\nimport com.alibaba.nacos.api.exception.NacosException;\nimport com.alibaba.nacos.api.naming.NamingService;\nimport com.alibaba.nacos.api.naming.pojo.Instance;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport java.util.List;\n\nimport static org.springframework.web.bind.annotation.RequestMethod.GET;\n\n@Controller\n@RequestMapping("discovery")\npublic class DiscoveryController {\n\n @NacosInjected\n private NamingService namingService;\n\n @RequestMapping(value = "/get", method = GET)\n @ResponseBody\n public List get(@RequestParam String serviceName) throws NacosException {\n return namingService.getAllInstances(serviceName);\n }\n}'}},{key:"getSpringBootCode",value:function(e){return'/* Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-boot-example/nacos-spring-boot-discovery-example\n* pom.xml\n \n com.alibaba.boot\n nacos-discovery-spring-boot-starter\n ${latest.version}\n \n*/\n/* Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-boot-example/nacos-spring-boot-discovery-example/src/main/resources\n* application.properties\n nacos.discovery.server-addr=127.0.0.1:8848\n*/\n// Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-boot-example/nacos-spring-boot-discovery-example/src/main/java/com/alibaba/nacos/example/spring/boot/controller\n\npackage com.alibaba.nacos.example.spring.boot.controller;\n\nimport com.alibaba.nacos.api.annotation.NacosInjected;\nimport com.alibaba.nacos.api.exception.NacosException;\nimport com.alibaba.nacos.api.naming.NamingService;\nimport com.alibaba.nacos.api.naming.pojo.Instance;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport java.util.List;\n\nimport static org.springframework.web.bind.annotation.RequestMethod.GET;\n\n@Controller\n@RequestMapping("discovery")\npublic class DiscoveryController {\n\n @NacosInjected\n private NamingService namingService;\n\n @RequestMapping(value = "/get", method = GET)\n @ResponseBody\n public List get(@RequestParam String serviceName) throws NacosException {\n return namingService.getAllInstances(serviceName);\n }\n}'}},{key:"getSpringCloudCode",value:function(e){return"/* Refer to document: https://github.com/nacos-group/nacos-examples/blob/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/\n* pom.xml\n \n org.springframework.cloud\n spring-cloud-starter-alibaba-nacos-discovery\n ${latest.version}\n \n*/\n\n// nacos-spring-cloud-provider-example\n\n/* Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-provider-example/src/main/resources\n* application.properties\nserver.port=18080\nspring.application.name=".concat(this.record.name,'\nspring.cloud.nacos.discovery.server-addr=127.0.0.1:8848\n*/\n\n// Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-provider-example/src/main/java/com/alibaba/nacos/example/spring/cloud\npackage com.alibaba.nacos.example.spring.cloud;\n\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.client.discovery.EnableDiscoveryClient;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RestController;\n\n/**\n * @author xiaojing\n */\n@SpringBootApplication\n@EnableDiscoveryClient\npublic class NacosProviderApplication {\n\n public static void main(String[] args) {\n SpringApplication.run(NacosProviderApplication.class, args);\n}\n\n @RestController\n class EchoController {\n @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)\n public String echo(@PathVariable String string) {\n return "Hello Nacos Discovery " + string;\n }\n }\n}\n\n// nacos-spring-cloud-consumer-example\n\n/* Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-consumer-example/src/main/resources\n* application.properties\nspring.application.name=micro-service-oauth2\nspring.cloud.nacos.discovery.server-addr=127.0.0.1:8848\n*/\n\n// Refer to document: https://github.com/nacos-group/nacos-examples/tree/master/nacos-spring-cloud-example/nacos-spring-cloud-discovery-example/nacos-spring-cloud-consumer-example/src/main/java/com/alibaba/nacos/example/spring/cloud\npackage com.alibaba.nacos.example.spring.cloud;\n\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.boot.SpringApplication;\nimport org.springframework.boot.autoconfigure.SpringBootApplication;\nimport org.springframework.cloud.client.discovery.EnableDiscoveryClient;\nimport org.springframework.cloud.client.loadbalancer.LoadBalanced;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RestController;\nimport org.springframework.web.client.RestTemplate;\n\n/**\n * @author xiaojing\n */\n@SpringBootApplication\n@EnableDiscoveryClient\npublic class NacosConsumerApplication {\n\n @LoadBalanced\n @Bean\n public RestTemplate restTemplate() {\n return new RestTemplate();\n }\n\n public static void main(String[] args) {\n SpringApplication.run(NacosConsumerApplication.class, args);\n }\n\n @RestController\n public class TestController {\n\n private final RestTemplate restTemplate;\n\n @Autowired\n public TestController(RestTemplate restTemplate) {this.restTemplate = restTemplate;}\n\n @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)\n public String echo(@PathVariable String str) {\n return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);\n }\n }\n}')}},{key:"getNodejsCode",value:function(e){return"TODO"}},{key:"getCppCode",value:function(e){return"TODO"}},{key:"getShellCode",value:function(e){return"TODO"}},{key:"getPythonCode",value:function(e){return'/*\n* Demo for Nacos\n*/\nimport json\nimport socket\n\nimport nacos\n\n\ndef get_host_ip():\n res = socket.gethostbyname(socket.gethostname())\n return res\n\n\ndef load_config(content):\n _config = json.loads(content)\n return _config\n\n\ndef nacos_config_callback(args):\n content = args[\'raw_content\']\n load_config(content)\n\n\nclass NacosClient:\n service_name = None\n service_port = None\n service_group = None\n\n def __init__(self, server_endpoint, namespace_id, username=None, password=None):\n self.client = nacos.NacosClient(server_endpoint,\n namespace=namespace_id,\n username=username,\n password=password)\n self.endpoint = server_endpoint\n self.service_ip = get_host_ip()\n\n def register(self):\n self.client.add_naming_instance(self.service_name,\n self.service_ip,\n self.service_port,\n group_name=self.service_group)\n\n def modify(self, service_name, service_ip=None, service_port=None):\n self.client.modify_naming_instance(service_name,\n service_ip if service_ip else self.service_ip,\n service_port if service_port else self.service_port)\n\n def unregister(self):\n self.client.remove_naming_instance(self.service_name,\n self.service_ip,\n self.service_port)\n\n def set_service(self, service_name, service_ip, service_port, service_group):\n self.service_name = service_name\n self.service_ip = service_ip\n self.service_port = service_port\n self.service_group = service_group\n\n async def beat_callback(self):\n self.client.send_heartbeat(self.service_name,\n self.service_ip,\n self.service_port)\n\n def load_conf(self, data_id, group):\n return self.client.get_config(data_id=data_id, group=group, no_snapshot=True)\n\n def add_conf_watcher(self, data_id, group, callback):\n self.client.add_config_watcher(data_id=data_id, group=group, cb=callback)\n\n\nif __name__ == \'__main__\':\n nacos_config = {\n "nacos_data_id":"test",\n "nacos_server_ip":"127.0.0.1",\n "nacos_namespace":"public",\n "nacos_groupName":"DEFAULT_GROUP",\n "nacos_user":"nacos",\n "nacos_password":"1234567"\n }\n nacos_data_id = nacos_config["nacos_data_id"]\n SERVER_ADDRESSES = nacos_config["nacos_server_ip"]\n NAMESPACE = nacos_config["nacos_namespace"]\n groupName = nacos_config["nacos_groupName"]\n user = nacos_config["nacos_user"]\n password = nacos_config["nacos_password"]\n # todo 将另一个路由对象(通常定义在其他模块或文件中)合并到主应用(app)中。\n # app.include_router(custom_api.router, tags=[\'test\'])\n service_ip = get_host_ip()\n client = NacosClient(SERVER_ADDRESSES, NAMESPACE, user, password)\n client.add_conf_watcher(nacos_data_id, groupName, nacos_config_callback)\n\n # 启动时,强制同步一次配置\n data_stream = client.load_conf(nacos_data_id, groupName)\n json_config = load_config(data_stream)\n #设定服务\n client.set_service(json_config["service_name"], json_config.get("service_ip", service_ip), service_port, groupName)\n #注册服务\n client.register()\n #下线服务\n client.unregister()\n'}},{key:"getCSharpCode",value:function(e){return'/* Refer to document: https://github.com/nacos-group/nacos-sdk-csharp/\nDemo for Basic Nacos Opreation\nApp.csproj\n\n\n \n\n*/\n\nusing Microsoft.Extensions.DependencyInjection;\nusing Nacos.V2;\nusing Nacos.V2.DependencyInjection;\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\n\nclass Program\n{\n static async Task Main(string[] args)\n {\n IServiceCollection services = new ServiceCollection();\n\n services.AddNacosV2Naming(x =>\n {\n x.ServerAddresses = new List { "http://localhost:8848/" };\n x.Namespace = "cs-test";\n\n // swich to use http or rpc\n x.NamingUseRpc = true;\n });\n\n IServiceProvider serviceProvider = services.BuildServiceProvider();\n var namingSvc = serviceProvider.GetService();\n\n await namingSvc.RegisterInstance("'.concat(this.record.name,'", "11.11.11.11", 8888, "TEST1");\n\n await namingSvc.RegisterInstance("').concat(this.record.name,'", "2.2.2.2", 9999, "DEFAULT");\n\n Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(await namingSvc.GetAllInstances("').concat(this.record.name,'")));\n\n await namingSvc.DeregisterInstance("').concat(this.record.name,'", "2.2.2.2", 9999, "DEFAULT");\n\n var listener = new EventListener();\n\n await namingSvc.Subscribe("').concat(this.record.name,'", listener);\n }\n\n internal class EventListener : IEventListener\n {\n public Task OnEvent(IEvent @event)\n {\n Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(@event));\n return Task.CompletedTask;\n }\n }\n}\n\n/* Refer to document: https://github.com/nacos-group/nacos-sdk-csharp/\nDemo for ASP.NET Core Integration\nApp.csproj\n\n\n \n\n*/\n\n/* Refer to document: https://github.com/nacos-group/nacos-sdk-csharp/blob/dev/samples/App1/appsettings.json\n* appsettings.json\n{\n "nacos": {\n "ServerAddresses": [ "http://localhost:8848" ],\n "DefaultTimeOut": 15000,\n "Namespace": "cs",\n "ServiceName": "App1",\n "GroupName": "DEFAULT_GROUP",\n "ClusterName": "DEFAULT",\n "Port": 0,\n "Weight": 100,\n "RegisterEnabled": true,\n "InstanceEnabled": true,\n "Ephemeral": true,\n "NamingUseRpc": true,\n "NamingLoadCacheAtStart": ""\n }\n}\n*/\n\n// Refer to document: https://github.com/nacos-group/nacos-sdk-csharp/blob/dev/samples/App1/Startup.cs\nusing Nacos.AspNetCore.V2;\n\npublic class Startup\n{\n public Startup(IConfiguration configuration)\n {\n Configuration = configuration;\n }\n\n public IConfiguration Configuration { get; }\n\n public void ConfigureServices(IServiceCollection services)\n {\n // ....\n services.AddNacosAspNet(Configuration);\n }\n\n public void Configure(IApplicationBuilder app, IWebHostEnvironment env)\n {\n // ....\n }\n}\n ')}},{key:"openDialog",value:function(e){var t=this;this.setState({dialogvisible:!0}),this.record=e,setTimeout(function(){t.getData()})}},{key:"closeDialog",value:function(){this.setState({dialogvisible:!1})}},{key:"createCodeMirror",value:function(e,t){var n=this.refs.codepreview;n&&(n.innerHTML="",this.cm=window.CodeMirror(n,{value:t,mode:e,height:400,width:500,lineNumbers:!0,theme:"xq-light",lint:!0,tabMode:"indent",autoMatchParens:!0,textWrapping:!0,gutters:["CodeMirror-lint-markers"],extraKeys:{F1:function(e){e.setOption("fullScreen",!e.getOption("fullScreen"))},Esc:function(e){e.getOption("fullScreen")&&e.setOption("fullScreen",!1)}}}),this.cm.setSize("auto","490px"))}},{key:"changeTab",value:function(e,t){var n=this;setTimeout(function(){n[e]=!0,n.createCodeMirror("text/javascript",t)})}},{key:"render",value:function(){var e=this.props.locale,e=void 0===e?{}:e;return O.a.createElement("div",null,O.a.createElement(o.a,{title:e.sampleCode,style:{width:"80%"},visible:this.state.dialogvisible,footer:O.a.createElement("div",null),onClose:this.closeDialog.bind(this)},O.a.createElement("div",{style:{height:500}},O.a.createElement(h.a,{tip:e.loading,style:{width:"100%"},visible:this.state.loading},O.a.createElement(m.a,{shape:"text",style:{height:40,paddingBottom:10}},O.a.createElement(g,{title:"Java",key:0,onClick:this.changeTab.bind(this,"commoneditor1",this.defaultCode)}),O.a.createElement(g,{title:"Spring",key:1,onClick:this.changeTab.bind(this,"commoneditor1",this.springCode)}),O.a.createElement(g,{title:"Spring Boot",key:2,onClick:this.changeTab.bind(this,"commoneditor2",this.sprigbootCode)}),O.a.createElement(g,{title:"Spring Cloud",key:21,onClick:this.changeTab.bind(this,"commoneditor21",this.sprigcloudCode)}),O.a.createElement(g,{title:"Node.js",key:3,onClick:this.changeTab.bind(this,"commoneditor3",this.nodejsCode)}),O.a.createElement(g,{title:"C++",key:4,onClick:this.changeTab.bind(this,"commoneditor4",this.cppCode)}),O.a.createElement(g,{title:"Shell",key:5,onClick:this.changeTab.bind(this,"commoneditor5",this.shellCode)}),O.a.createElement(g,{title:"Python",key:6,onClick:this.changeTab.bind(this,"commoneditor6",this.pythonCode)}),O.a.createElement(g,{title:"C#",key:7,onClick:this.changeTab.bind(this,"commoneditor7",this.csharpCode)})),O.a.createElement("div",{ref:"codepreview"})))))}}]),n}(O.a.Component)).displayName="ShowServiceCodeing",f=f))||f,Y=t(51),I=t(146),A=(t(778),t(22)),R=L.a.Item,H=d.a.Row,F=d.a.Col,z=T.a.Column,d=(0,n.a.config)(((f=function(e){Object(u.a)(n,e);var t=Object(c.a)(n);function n(e){var a;return Object(s.a)(this,n),(a=t.call(this,e)).getQueryLater=function(){setTimeout(function(){return a.queryServiceList()})},a.showcode=function(){setTimeout(function(){return a.queryServiceList()})},a.setNowNameSpace=function(e,t,n){return a.setState({nowNamespaceName:e,nowNamespaceId:t,nowNamespaceDesc:n})},a.rowColor=function(e){return{className:e.healthyInstanceCount?"":"row-bg-red"}},a.editServiceDialog=O.a.createRef(),a.showcode=O.a.createRef(),a.state={loading:!1,total:0,pageSize:10,currentPage:1,dataSource:[],search:{serviceName:Object(p.b)("serviceNameParam")||"",groupName:Object(p.b)("groupNameParam")||""},hasIpCount:!("false"===localStorage.getItem("hasIpCount"))},a.field=new i.a(Object(l.a)(a)),a}return Object(a.a)(n,[{key:"openLoading",value:function(){this.setState({loading:!0})}},{key:"closeLoading",value:function(){this.setState({loading:!1})}},{key:"openEditServiceDialog",value:function(){try{this.editServiceDialog.current.getInstance().show(this.state.service)}catch(e){}}},{key:"queryServiceList",value:function(){var n=this,e=this.state,t=e.currentPage,a=e.pageSize,r=e.search,o=e.withInstances,o=void 0!==o&&o,e=e.hasIpCount,e=["hasIpCount=".concat(e),"withInstances=".concat(o),"pageNo=".concat(t),"pageSize=".concat(a),"serviceNameParam=".concat(r.serviceName),"groupNameParam=".concat(r.groupName)];Object(p.f)({serviceNameParam:r.serviceName,groupNameParam:r.groupName}),this.openLoading(),Object(p.e)({url:"v1/ns/catalog/services?".concat(e.join("&")),success:function(){var e=0o&&v.a.createElement(u.a,{className:"users-pagination",current:i,total:n.totalCount,pageSize:o,onChange:function(e){return t.setState({pageNo:e},function(){return t.getUsers()})}}),v.a.createElement(E,{visible:s,onOk:function(e){return Object(_.c)(e).then(function(e){return t.setState({pageNo:1},function(){return t.getUsers()}),e})},onCancel:function(){return t.colseCreateUser()}}),v.a.createElement(x.a,{visible:l,username:e,onOk:function(e){return Object(_.k)(e).then(function(e){return t.getUsers(),e})},onCancel:function(){return t.setState({passwordResetUser:void 0,passwordResetUserVisible:!1})}}))}}]),n}(v.a.Component)).displayName="UserManagement",n=o))||n)||n;t.a=r},function(e,t,n){"use strict";n(67);var a=n(46),l=n.n(a),a=(n(35),n(17)),u=n.n(a),c=n(32),a=(n(66),n(21)),d=n.n(a),a=(n(34),n(20)),f=n.n(a),a=(n(93),n(55)),p=n.n(a),a=(n(38),n(2)),h=n.n(a),a=(n(37),n(10)),m=n.n(a),i=n(12),s=n(13),g=n(23),y=n(15),v=n(14),a=(n(27),n(6)),a=n.n(a),r=n(0),_=n.n(r),r=n(31),b=n(45),o=n(86),w=n(52),M=(n(49),n(28)),k=n.n(M),M=(n(59),n(29)),S=n.n(M),E=h.a.Item,x=S.a.Option,C={labelCol:{fixedSpan:4},wrapperCol:{span:19}},T=Object(r.b)(function(e){return{namespaces:e.namespace.namespaces}},{getNamespaces:o.b,searchRoles:b.l})(M=(0,a.a.config)(((M=function(e){Object(y.a)(o,e);var r=Object(v.a)(o);function o(){var t;Object(i.a)(this,o);for(var e=arguments.length,n=new Array(e),a=0;ai&&_.a.createElement(l.a,{className:"users-pagination",current:s,total:t.totalCount,pageSize:i,onChange:function(e){return a.setState({pageNo:e},function(){return a.getPermissions()})}}),_.a.createElement(T,{visible:n,onOk:function(e){return Object(b.a)(e).then(function(e){return a.setState({pageNo:1},function(){return a.getPermissions()}),e})},onCancel:function(){return a.colseCreatePermission()}}))}}]),n}(_.a.Component)).displayName="PermissionsManagement",n=M))||n)||n);t.a=r},function(e,t,n){"use strict";n(67);var a=n(46),l=n.n(a),a=(n(35),n(17)),u=n.n(a),a=(n(66),n(21)),c=n.n(a),a=(n(34),n(20)),d=n.n(a),a=(n(93),n(55)),f=n.n(a),a=(n(38),n(2)),p=n.n(a),a=(n(37),n(10)),h=n.n(a),i=n(12),s=n(13),m=n(23),g=n(15),y=n(14),a=(n(27),n(6)),a=n.n(a),r=n(0),v=n.n(r),r=n(31),_=n(45),b=n(52),o=(n(59),n(29)),w=n.n(o),o=(n(49),n(28)),M=n.n(o),k=p.a.Item,S={labelCol:{fixedSpan:4},wrapperCol:{span:19}},E=Object(r.b)(function(e){return{users:e.authority.users}},{searchUsers:_.m})(o=(0,a.a.config)(((o=function(e){Object(g.a)(o,e);var r=Object(y.a)(o);function o(){var t;Object(i.a)(this,o);for(var e=arguments.length,n=new Array(e),a=0;ao&&v.a.createElement(l.a,{className:"users-pagination",current:i,total:t.totalCount,pageSize:o,onChange:function(e){return a.setState({pageNo:e},function(){return a.getRoles()})}}),v.a.createElement(E,{visible:s,onOk:function(e){return Object(_.b)(e).then(function(e){return a.getRoles(),e})},onCancel:function(){return a.colseCreateRole()}}))}}]),n}(v.a.Component)).displayName="RolesManagement",n=o))||n)||n);t.a=r},function(e,t,n){"use strict";n(35);function l(e){var t=void 0===(t=localStorage.token)?"{}":t,t=(Object(_.c)(t)&&JSON.parse(t)||{}).globalAdmin,n=[];return"naming"===e?n.push(b):"config"===e?n.push(w):n.push(w,b),t&&n.push(M),n.push(k),n.push(S),n.push(E),n.filter(function(e){return e})}var a=n(17),u=n.n(a),a=(n(48),n(25)),c=n.n(a),a=(n(43),n(26)),d=n.n(a),r=n(12),o=n(13),i=n(15),s=n(14),a=(n(27),n(6)),a=n.n(a),f=n(19),p=(n(84),n(50)),h=n.n(p),p=n(0),m=n.n(p),p=n(39),g=n(31),y=n(108),v=n(54),_=n(47),b={key:"serviceManagementVirtual",children:[{key:"serviceManagement",url:"/serviceManagement"},{key:"subscriberList",url:"/subscriberList"}]},w={key:"configurationManagementVirtual",children:[{key:"configurationManagement",url:"/configurationManagement"},{key:"historyRollback",url:"/historyRollback"},{key:"listeningToQuery",url:"/listeningToQuery"}]},M={key:"authorityControl",children:[{key:"userList",url:"/userManagement"},{key:"roleManagement",url:"/rolesManagement"},{key:"privilegeManagement",url:"/permissionsManagement"}]},k={key:"namespace",url:"/namespace"},S={key:"clusterManagementVirtual",children:[{key:"clusterManagement",url:"/clusterManagement"}]},E={key:"settingCenter",url:"/settingCenter"},x=(n(386),h.a.SubMenu),C=h.a.Item,p=(n=Object(g.b)(function(e){return Object(f.a)(Object(f.a)({},e.locale),e.base)},{getState:v.e,getNotice:v.d,getGuide:v.c}),g=a.a.config,Object(p.g)(a=n(a=g(((v=function(e){Object(i.a)(n,e);var t=Object(s.a)(n);function n(e){return Object(r.a)(this,n),(e=t.call(this,e)).state={visible:!0},e}return Object(o.a)(n,[{key:"componentDidMount",value:function(){this.props.getState(),this.props.getNotice(),this.props.getGuide()}},{key:"goBack",value:function(){this.props.history.goBack()}},{key:"navTo",value:function(e){var t=this.props.location.search,t=new URLSearchParams(t);t.set("namespace",window.nownamespace),t.set("namespaceShowName",window.namespaceShowName),this.props.history.push([e,"?",t.toString()].join(""))}},{key:"isCurrentPath",value:function(e){return e===this.props.location.pathname?"current-path next-selected":void 0}},{key:"defaultOpenKeys",value:function(){for(var t=this,e=l(this.props.functionMode),n=0,a=e.length;nthis.state.pageSize&&S.a.createElement("div",{style:{marginTop:10,textAlign:"right"}},S.a.createElement(v.a,{current:this.state.pageNo,total:a,pageSize:this.state.pageSize,onChange:function(e){return t.setState({pageNo:e},function(){return t.querySubscriberList()})}}))))}}]),n}(S.a.Component)).displayName="SubscriberList",d=n))||d)||d;t.a=f},function(e,t,n){"use strict";n(53);var a=n(36),c=n.n(a),a=(n(67),n(46)),d=n.n(a),a=(n(179),n(78)),f=n.n(a),a=(n(37),n(10)),p=n.n(a),a=(n(34),n(20)),h=n.n(a),a=(n(35),n(17)),r=n.n(a),a=(n(48),n(25)),o=n.n(a),a=(n(49),n(28)),i=n.n(a),s=n(12),l=n(13),u=n(23),m=n(15),g=n(14),a=(n(27),n(6)),a=n.n(a),y=(n(421),n(123)),v=n.n(y),y=(n(66),n(21)),_=n.n(y),y=(n(69),n(40)),y=n.n(y),b=(n(38),n(2)),w=n.n(b),b=n(0),M=n.n(b),k=n(1),b=n(144),S=n.n(b),E=n(51),x=(n(781),w.a.Item),C=y.a.Row,T=y.a.Col,L=_.a.Column,O=v.a.Panel,y=(0,a.a.config)(((b=function(e){Object(m.a)(a,e);var t=Object(g.a)(a);function a(e){var n;return Object(s.a)(this,a),(n=t.call(this,e)).getQueryLater=function(){setTimeout(function(){return n.queryClusterStateList()})},n.setNowNameSpace=function(e,t){return n.setState({nowNamespaceName:e,nowNamespaceId:t})},n.rowColor=function(e){return{className:(e.voteFor,"")}},n.state={loading:!1,total:0,pageSize:10,currentPage:1,keyword:"",dataSource:[]},n.field=new i.a(Object(u.a)(n)),n}return Object(l.a)(a,[{key:"componentDidMount",value:function(){this.getQueryLater()}},{key:"openLoading",value:function(){this.setState({loading:!0})}},{key:"closeLoading",value:function(){this.setState({loading:!1})}},{key:"queryClusterStateList",value:function(){var n=this,e=this.state,t=e.currentPage,a=e.pageSize,r=e.keyword,e=e.withInstances,e=["withInstances=".concat(void 0!==e&&e),"pageNo=".concat(t),"pageSize=".concat(a),"keyword=".concat(r)];Object(k.e)({url:"v1/core/cluster/nodes?".concat(e.join("&")),beforeSend:function(){return n.openLoading()},success:function(){var e=0this.state.pageSize&&M.a.createElement("div",{style:{marginTop:10,textAlign:"right"}},M.a.createElement(d.a,{current:this.state.currentPage,total:this.state.total,pageSize:this.state.pageSize,onChange:function(e){return t.setState({currentPage:e},function(){return t.queryClusterStateList()})}}))))}}]),a}(M.a.Component)).displayName="ClusterNodeList",n=b))||n;t.a=y},function(e,t,n){"use strict";n(34);var a=n(20),i=n.n(a),s=n(12),l=n(13),u=n(15),c=n(14),a=(n(27),n(6)),a=n.n(a),r=n(19),o=(n(114),n(75)),o=n.n(o),d=n(0),f=n.n(d),p=(n(784),n(51)),d=n(87),h=n(148),m=n(149),g=n(31),y=n(22),v=o.a.Group,g=Object(g.b)(function(e){return Object(r.a)({},e.locale)},{changeLanguage:d.a,changeTheme:h.a,changeNameShow:m.a})(o=(0,a.a.config)(((n=function(e){Object(u.a)(o,e);var r=Object(c.a)(o);function o(e){Object(s.a)(this,o),e=r.call(this,e);var t=localStorage.getItem(y.p),n=localStorage.getItem(y.j),a=localStorage.getItem(y.g);return e.state={theme:"dark"===t?"dark":"light",language:"en-US"===a?"en-US":"zh-CN",nameShow:"select"===n?"select":"label"},e}return Object(l.a)(o,[{key:"newTheme",value:function(e){this.setState({theme:e})}},{key:"newLanguage",value:function(e){this.setState({language:e})}},{key:"newNameShow",value:function(e){this.setState({nameShow:e})}},{key:"submit",value:function(){var e=this.props,t=e.changeLanguage,n=e.changeTheme,e=e.changeNameShow,a=this.state.language,r=this.state.theme,o=this.state.nameShow;t(a),n(r),e(o)}},{key:"render",value:function(){var e=this.props.locale,e=void 0===e?{}:e,t=[{value:"light",label:e.settingLight},{value:"dark",label:e.settingDark}],n=[{value:"select",label:e.settingShowSelect},{value:"label",label:e.settingShowLabel}];return f.a.createElement(f.a.Fragment,null,f.a.createElement(p.a,{title:e.settingTitle}),f.a.createElement("div",{className:"setting-box"},f.a.createElement("div",{className:"text-box"},f.a.createElement("div",{className:"setting-checkbox"},f.a.createElement("div",{className:"setting-span"},e.settingTheme),f.a.createElement(v,{dataSource:t,value:this.state.theme,onChange:this.newTheme.bind(this)})),f.a.createElement("div",{className:"setting-checkbox"},f.a.createElement("div",{className:"setting-span"},e.settingLocale),f.a.createElement(v,{dataSource:[{value:"en-US",label:"English"},{value:"zh-CN",label:"中文"}],value:this.state.language,onChange:this.newLanguage.bind(this)})),f.a.createElement("div",{className:"setting-checkbox"},f.a.createElement("div",{className:"setting-span"},e.settingShow),f.a.createElement(v,{dataSource:n,value:this.state.nameShow,onChange:this.newNameShow.bind(this)}))),f.a.createElement(i.a,{type:"primary",onClick:this.submit.bind(this)},e.settingSubmit)))}}]),o}(f.a.Component)).displayName="SettingCenter",o=n))||o)||o;t.a=g},function(e,t,V){"use strict";V.r(t),function(e){V(53);var t=V(36),a=V.n(t),t=(V(27),V(6)),r=V.n(t),o=V(12),i=V(13),s=V(15),l=V(14),n=V(19),t=V(0),u=V.n(t),t=V(24),t=V.n(t),c=V(125),d=V(429),f=V(440),p=V(31),h=V(39),m=V(73),g=(V(477),V(449)),y=V(22),v=V(450),_=V(451),b=V(443),w=V(452),M=V(453),k=V(444),S=V(454),E=V(455),x=V(456),C=V(457),T=V(458),L=V(441),O=V(445),D=V(442),N=V(459),P=V(460),j=V(446),I=V(447),A=V(448),R=V(438),H=V(461),Y=V(439),F=V(87),z=V(54),W=V(148),B=V(149),e=(V(785),e.hot,localStorage.getItem(y.g)||localStorage.setItem(y.g,"zh-CN"===navigator.language?"zh-CN":"en-US"),Object(c.b)(Object(n.a)(Object(n.a)({},Y.a),{},{routing:d.routerReducer}))),Y=Object(c.d)(e,Object(c.c)(Object(c.a)(f.a),window[y.l]?window[y.l]():function(e){return e})),U=[{path:"/",exact:!0,render:function(){return u.a.createElement(h.a,{to:"/welcome"})}},{path:"/welcome",component:R.a},{path:"/namespace",component:b.a},{path:"/newconfig",component:w.a},{path:"/configsync",component:M.a},{path:"/configdetail",component:k.a},{path:"/configeditor",component:S.a},{path:"/historyDetail",component:E.a},{path:"/configRollback",component:x.a},{path:"/historyRollback",component:C.a},{path:"/listeningToQuery",component:T.a},{path:"/configurationManagement",component:L.a},{path:"/serviceManagement",component:O.a},{path:"/serviceDetail",component:D.a},{path:"/subscriberList",component:N.a},{path:"/clusterManagement",component:P.a},{path:"/userManagement",component:j.a},{path:"/rolesManagement",component:A.a},{path:"/permissionsManagement",component:I.a},{path:"/settingCenter",component:H.a}],e=Object(p.b)(function(e){return Object(n.a)(Object(n.a)({},e.locale),e.base)},{changeLanguage:F.a,getState:z.e,changeTheme:W.a,changeNameShow:B.a})(d=function(e){Object(s.a)(n,e);var t=Object(l.a)(n);function n(e){return Object(o.a)(this,n),(e=t.call(this,e)).state={shownotice:"none",noticecontent:"",nacosLoading:{}},e}return Object(i.a)(n,[{key:"componentDidMount",value:function(){this.props.getState();var e=localStorage.getItem(y.g),t=localStorage.getItem(y.p),n=localStorage.getItem(y.j);this.props.changeLanguage(e),this.props.changeTheme(t),this.props.changeNameShow(n)}},{key:"router",get:function(){var e=this.props,t=e.loginPageEnabled,e=e.consoleUiEnable;return u.a.createElement(m.a,null,u.a.createElement(h.d,null,t&&"false"===t?null:u.a.createElement(h.b,{path:"/login",component:v.a}),u.a.createElement(h.b,{path:"/register",component:_.a}),u.a.createElement(g.a,null,e&&"true"===e&&U.map(function(e){return u.a.createElement(h.b,Object.assign({key:e.path},e))}))))}},{key:"render",value:function(){var e=this.props,t=e.locale,e=e.loginPageEnabled;return u.a.createElement(a.a,Object.assign({className:"nacos-loading",shape:"flower",tip:"loading...",visible:!e,fullScreen:!0},this.state.nacosLoading),u.a.createElement(r.a,{locale:t},this.router))}}]),n}(u.a.Component))||d;t.a.render(u.a.createElement(p.a,{store:Y},u.a.createElement(e,null)),document.getElementById("root"))}.call(this,V(463)(e))},function(e,t){e.exports=function(e){var t;return e.webpackPolyfill||((t=Object.create(e)).children||(t.children=[]),Object.defineProperty(t,"loaded",{enumerable:!0,get:function(){return t.l}}),Object.defineProperty(t,"id",{enumerable:!0,get:function(){return t.i}}),Object.defineProperty(t,"exports",{enumerable:!0}),t.webpackPolyfill=1),t}},function(e,t,n){},function(e,t,n){},function(e,t,n){},function(e,t,n){},function(e,t,n){},function(I,e,t){"use strict"; +/** @license React v16.14.0 + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var c=t(200),t="function"==typeof Symbol&&Symbol.for,d=t?Symbol.for("react.element"):60103,u=t?Symbol.for("react.portal"):60106,n=t?Symbol.for("react.fragment"):60107,a=t?Symbol.for("react.strict_mode"):60108,r=t?Symbol.for("react.profiler"):60114,o=t?Symbol.for("react.provider"):60109,i=t?Symbol.for("react.context"):60110,s=t?Symbol.for("react.forward_ref"):60112,l=t?Symbol.for("react.suspense"):60113,f=t?Symbol.for("react.memo"):60115,p=t?Symbol.for("react.lazy"):60116,h="function"==typeof Symbol&&Symbol.iterator;function m(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n