summaryrefslogtreecommitdiffstats
path: root/vid-app-common/src
diff options
context:
space:
mode:
Diffstat (limited to 'vid-app-common/src')
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java10
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java8
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstance.java4
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/asdc/beans/Service.java16
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java14
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/controller/AaiController2.java3
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java13
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java34
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/controller/VidController.java16
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt47
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt3
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt28
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/ExceptionResponse.java5
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/ServiceInstanceSearchResult.java65
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/BaseResource.java23
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroup.java12
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroupMember.java5
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Network.java12
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java5
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java3
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java40
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Vnf.java16
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/mso/MsoUtil.java45
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/mso/model/ServiceInstantiationRequestDetails.java35
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt7
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/properties/FeatureSetsManager.kt82
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/properties/Features.java6
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/properties/FeaturesTogglingConfiguration.java13
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/AlwaysValidRoleValidator.java6
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/PermissionProperties.kt34
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/Role.java33
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/RoleProvider.java25
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java21
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByOwningEntity.java64
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceType.java (renamed from vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByRoles.java)45
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorFactory.java63
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorsComposer.kt16
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java103
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogicImpl.java28
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java34
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/services/UserParamsContainer.kt40
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/utils/KotlinUtils.kt4
-rw-r--r--vid-app-common/src/main/java/org/onap/vid/utils/Logging.java3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/angular-moment/moment.min.js2
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js236
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js3
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/InstantiationController.js1
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js2
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/creationDialogController.js14
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/services/dataService.js8
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/aai/SubscriberFilteredResultsTest.java6
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/bl/AaiServiceTest.java177
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java36
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java14
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/controller/LoggerControllerTest.java8
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/controller/ServicePermissionsTest.java3
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/controller/VidControllerTest.java62
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java14
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt90
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java59
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/model/ServiceInstanceSearchResultTest.java188
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/InstantiationModelSerializationTest.java23
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java62
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/mso/MsoUtilTest.java23
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/mso/model/RequestParametersVfModuleTest.java49
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/properties/FeatureSetsManagerTest.kt101
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/AlwaysValidRoleValidatorTest.java3
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/RoleProviderTest.java41
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByOwningEntityTest.java90
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByRolesTest.java114
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceTypeTest.java111
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorFactoryTest.java77
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorsComposerTest.java110
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/AAITreeNodeBuilderTest.java19
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/AaiServiceImplTest.java2
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/AaiServiceTest.java153
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBaseTest.java35
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBusinessLogicTest.java44
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/InstantiationTemplatesServiceTest.java68
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/MsoRequestBuilderTest.java118
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/services/UserParamsContainerTest.kt57
-rw-r--r--vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java38
-rw-r--r--vid-app-common/src/test/resources/example.features.properties1
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfModuleDelete1Create1None1Request.json3
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfmodule/replace_vfmodule__payload_to_mso.json1
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json2
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__payload_to_mso.json2
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request.json21
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_instance_name.json19
-rw-r--r--vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_volume_group.json21
-rw-r--r--vid-app-common/src/test/resources/responses/aai/listServicesByOwningEntity.json97
-rw-r--r--vid-app-common/src/test/resources/responses/aai/listServicesByProject.json95
92 files changed, 2553 insertions, 1059 deletions
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java
index 159401009..78164462c 100644
--- a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java
+++ b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java
@@ -143,13 +143,13 @@ public class AaiClient implements AaiClientInterface {
}
@Override
- public AaiResponse getServicesByOwningEntityId(List<String> owningEntityIds){
+ public AaiResponse<OwningEntityResponse> getServicesByOwningEntityId(List<String> owningEntityIds){
Response resp = doAaiGet(getUrlFromLIst("business/owning-entities?", "owning-entity-id=", owningEntityIds), false);
return processAaiResponse(resp, OwningEntityResponse.class, null);
}
@Override
- public AaiResponse getServicesByProjectNames(List<String> projectNames){
+ public AaiResponse<ProjectResponse> getServicesByProjectNames(List<String> projectNames){
Response resp = doAaiGet(getUrlFromLIst("business/projects?", "project-name=", projectNames), false);
return processAaiResponse(resp, ProjectResponse.class, null);
}
@@ -528,9 +528,9 @@ public class AaiClient implements AaiClientInterface {
}
@Override
- public AaiResponse getSubscriberData(String subscriberId, boolean omitServiceInstances) {
+ public AaiResponse<Services> getSubscriberData(String subscriberId, boolean omitServiceInstances) {
String depth = omitServiceInstances ? "1" : "2";
- AaiResponse subscriberDataResponse;
+ AaiResponse<Services> subscriberDataResponse;
Response resp = doAaiGet(BUSINESS_CUSTOMERS_CUSTOMER + subscriberId + "?depth=" + depth, false);
subscriberDataResponse = processAaiResponse(resp, Services.class, null);
return subscriberDataResponse;
@@ -617,7 +617,7 @@ public class AaiClient implements AaiClientInterface {
}
}
- private AaiResponse processAaiResponse(Response resp, Class classType, String responseBody) {
+ private <T> AaiResponse<T> processAaiResponse(Response resp, Class<? extends T> classType, String responseBody) {
return processAaiResponse(resp, classType, responseBody, VidObjectMapperType.CODEHAUS);
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java
index 2a879e295..b4b908cc3 100644
--- a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java
+++ b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClientInterface.java
@@ -29,7 +29,9 @@ import org.onap.vid.aai.model.AaiGetOperationalEnvironments.OperationalEnvironme
import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.onap.vid.aai.model.ModelVer;
+import org.onap.vid.aai.model.OwningEntityResponse;
import org.onap.vid.aai.model.PortDetailsTranslator;
+import org.onap.vid.aai.model.ProjectResponse;
import org.onap.vid.aai.model.Properties;
import org.onap.vid.aai.model.ResourceType;
import org.onap.vid.model.SubscriberList;
@@ -49,11 +51,11 @@ public interface AaiClientInterface extends ProbeInterface {
AaiResponse<SubscriberList> getAllSubscribers();
- AaiResponse getSubscriberData(String subscriberId, boolean omitServiceInstances);
+ AaiResponse<Services> getSubscriberData(String subscriberId, boolean omitServiceInstances);
AaiResponse getServices();
- AaiResponse getServicesByOwningEntityId(List<String> owningEntityIds);
+ AaiResponse<OwningEntityResponse> getServicesByOwningEntityId(List<String> owningEntityIds);
AaiResponse<GetTenantsResponse[]> getTenants(String globalCustomerId, String serviceType);
@@ -75,7 +77,7 @@ public interface AaiClientInterface extends ProbeInterface {
ModelVer getLatestVersionByInvariantId(String modelInvariantId);
- AaiResponse getServicesByProjectNames(List<String> projectNames);
+ AaiResponse<ProjectResponse> getServicesByProjectNames(List<String> projectNames);
AaiResponse getServiceModelsByDistributionStatus();
diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstance.java b/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstance.java
index bd1a3acf7..a4e7de00c 100644
--- a/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstance.java
+++ b/vid-app-common/src/main/java/org/onap/vid/aai/ServiceInstance.java
@@ -22,6 +22,7 @@ package org.onap.vid.aai;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.onap.vid.aai.model.RelationshipList;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ServiceInstance {
@@ -50,4 +51,7 @@ public class ServiceInstance {
@JsonProperty("model-version-id")
public String modelVersionId;
+ @JsonProperty("relationship-list")
+ public RelationshipList relationshipList;
+
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/asdc/beans/Service.java b/vid-app-common/src/main/java/org/onap/vid/asdc/beans/Service.java
index 0d37fb39e..f5dd5d85f 100644
--- a/vid-app-common/src/main/java/org/onap/vid/asdc/beans/Service.java
+++ b/vid-app-common/src/main/java/org/onap/vid/asdc/beans/Service.java
@@ -20,6 +20,9 @@
package org.onap.vid.asdc.beans;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
import java.util.Collection;
import java.util.UUID;
@@ -76,6 +79,9 @@ public class Service {
private Collection<SubResource> resources;
private String orchestrationType;
+
+ @JsonInclude(NON_NULL)
+ private Boolean isInstantiationTemplateExists;
public static class ServiceBuilder {
@@ -204,6 +210,11 @@ public class Service {
return orchestrationType;
}
+ public Boolean getIsInstantiationTemplateExists() {
+ return isInstantiationTemplateExists;
+ }
+
+
public void setUuid(String uuid) {
this.uuid = uuid;
}
@@ -256,12 +267,17 @@ public class Service {
this.orchestrationType = orchestrationType;
}
+ public void setIsInstantiationTemplateExists(Boolean isInstantiationTemplateExists) {
+ this.isInstantiationTemplateExists = isInstantiationTemplateExists;
+ }
+
@Override
public String toString() {
return uuid;
}
@Override
+
public int hashCode() {
return UUID.fromString(getUuid()).hashCode();
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java
index 563c9ff20..a9ce40bba 100644
--- a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java
+++ b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController.java
@@ -49,7 +49,6 @@ import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.onap.vid.aai.util.AAIRestInterface;
import org.onap.vid.model.VersionByInvariantIdsRequest;
import org.onap.vid.properties.Features;
-import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.roles.RoleValidator;
import org.onap.vid.services.AaiService;
@@ -137,7 +136,7 @@ public class AaiController extends RestrictedBaseController {
@RequestMapping(value = "/aai_get_services", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> doGetServices(HttpServletRequest request) throws IOException {
- RoleValidator roleValidator = RoleValidator.by(roleProvider.getUserRoles(request));
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse subscriberList = aaiService.getServices(roleValidator);
return aaiResponseToResponseEntity(subscriberList);
@@ -225,7 +224,7 @@ public class AaiController extends RestrictedBaseController {
@RequestMapping(value = "/aai_get_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getFullSubscriberList(HttpServletRequest request) throws IOException {
ResponseEntity<String> responseEntity;
- RoleValidator roleValidator = RoleValidator.by(roleProvider.getUserRoles(request));
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
SubscriberFilteredResults subscriberList = aaiService.getFullSubscriberList(roleValidator);
if (subscriberList.getHttpCode() == 200) {
responseEntity = new ResponseEntity<>(objectMapper.writeValueAsString(subscriberList.getSubscriberList()),
@@ -256,8 +255,7 @@ public class AaiController extends RestrictedBaseController {
@RequestMapping(value = "/aai_sub_details/{subscriberId}", method = RequestMethod.GET)
public ResponseEntity<String> getSubscriberDetails(HttpServletRequest request, @PathVariable("subscriberId") String subscriberId,
@RequestParam(value="omitServiceInstances", required = false, defaultValue = "false") boolean omitServiceInstances) throws IOException {
- List<Role> roles = roleProvider.getUserRoles(request);
- RoleValidator roleValidator = RoleValidator.by(roles);
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse subscriberData = aaiService.getSubscriberData(subscriberId, roleValidator,
featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH) && omitServiceInstances);
String httpMessage = subscriberData.getT() != null ? objectMapper.writeValueAsString(subscriberData.getT()) : subscriberData.getErrorMessage();
@@ -274,8 +272,7 @@ public class AaiController extends RestrictedBaseController {
@RequestParam(value = "owningEntity", required = false) List<String> owningEntities) throws IOException {
ResponseEntity responseEntity;
- List<Role> roles = roleProvider.getUserRoles(request);
- RoleValidator roleValidator = RoleValidator.by(roles);
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse<ServiceInstancesSearchResults> searchResult = aaiService
.getServiceInstanceSearchResults(subscriberId, instanceIdentifier, roleValidator, owningEntities, projects);
@@ -404,8 +401,7 @@ public class AaiController extends RestrictedBaseController {
ResponseEntity responseEntity;
try {
- List<Role> roles = roleProvider.getUserRoles(request);
- RoleValidator roleValidator = RoleValidator.by(roles);
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(request);
AaiResponse<GetTenantsResponse[]> response = aaiService
.getTenants(globalCustomerId, serviceType, roleValidator);
if (response.getHttpCode() == 200) {
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController2.java b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController2.java
index 6431282e7..2d7a9253e 100644
--- a/vid-app-common/src/main/java/org/onap/vid/controller/AaiController2.java
+++ b/vid-app-common/src/main/java/org/onap/vid/controller/AaiController2.java
@@ -33,6 +33,7 @@ import org.onap.vid.model.aaiTree.Network;
import org.onap.vid.model.aaiTree.RelatedVnf;
import org.onap.vid.model.aaiTree.VpnBinding;
import org.onap.vid.properties.Features;
+import org.onap.vid.roles.PermissionPropertiesSubscriberAndServiceType;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.services.AaiService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -94,7 +95,7 @@ public class AaiController2 extends VidRestrictedBaseController {
final boolean isEditPermitted = roleProvider
.getUserRolesValidator(request)
- .isServicePermitted(subscriberId, serviceType);
+ .isServicePermitted(new PermissionPropertiesSubscriberAndServiceType(subscriberId, serviceType));
return new Permissions(isEditPermitted);
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java b/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java
index 6c8a37262..ce8bbb50c 100644
--- a/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java
+++ b/vid-app-common/src/main/java/org/onap/vid/controller/AsyncInstantiationController.java
@@ -33,7 +33,9 @@ import org.onap.vid.model.ServiceInfo;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
import org.onap.vid.mso.MsoResponseWrapper2;
import org.onap.vid.properties.Features;
+import org.onap.vid.roles.AllPermissionProperties;
import org.onap.vid.roles.RoleProvider;
+import org.onap.vid.roles.RoleValidator;
import org.onap.vid.services.AsyncInstantiationBusinessLogic;
import org.onap.vid.services.AuditService;
import org.onap.vid.utils.SystemPropertiesWrapper;
@@ -165,8 +167,15 @@ public class AsyncInstantiationController extends VidRestrictedBaseController {
}
private void throwExceptionIfAccessDenied(ServiceInstantiation request, HttpServletRequest httpServletRequest, String userId) {
- if (featureManager.isActive(Features.FLAG_1906_INSTANTIATION_API_USER_VALIDATION) && !roleProvider.getUserRolesValidator(httpServletRequest).isServicePermitted(request.getGlobalSubscriberId(), request.getSubscriptionServiceType())) {
- throw new AccessDeniedException(String.format("User %s is not allowed to make this request", userId));
+ if (featureManager.isActive(Features.FLAG_1906_INSTANTIATION_API_USER_VALIDATION)) {
+ RoleValidator roleValidator = roleProvider.getUserRolesValidator(httpServletRequest);
+ if (!roleValidator.isServicePermitted(new AllPermissionProperties(
+ request.getGlobalSubscriberId(),
+ request.getSubscriptionServiceType(),
+ request.getOwningEntityId()))
+ ) {
+ throw new AccessDeniedException(String.format("User %s is not allowed to make this request", userId));
+ }
}
}
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java b/vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java
new file mode 100644
index 000000000..ba20997cd
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/controller/PreLoadController.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.controller;
+import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping(PreLoadController.PRE_LOAD)
+public class PreLoadController extends VidRestrictedBaseController{
+ public static final String PRE_LOAD = "preload";
+
+ @PostMapping()
+ public Boolean postPreload (HttpServletRequest request) {
+ return true;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/VidController.java b/vid-app-common/src/main/java/org/onap/vid/controller/VidController.java
index 15bc5ed7c..d257000bf 100644
--- a/vid-app-common/src/main/java/org/onap/vid/controller/VidController.java
+++ b/vid-app-common/src/main/java/org/onap/vid/controller/VidController.java
@@ -21,16 +21,19 @@
package org.onap.vid.controller;
+import java.util.Collection;
import org.onap.portalsdk.core.controller.RestrictedBaseController;
import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
import org.onap.vid.asdc.AsdcCatalogException;
import org.onap.vid.asdc.beans.SecureServices;
+import org.onap.vid.asdc.beans.Service;
import org.onap.vid.exceptions.VidServiceUnavailableException;
import org.onap.vid.model.PombaInstance.PombaRequest;
import org.onap.vid.model.ServiceModel;
import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.services.AaiService;
+import org.onap.vid.services.InstantiationTemplatesService;
import org.onap.vid.services.PombaService;
import org.onap.vid.services.VidService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -50,14 +53,16 @@ public class VidController extends RestrictedBaseController {
private final AaiService aaiService;
private final RoleProvider roleProvider;
private final PombaService pombaService;
+ private final InstantiationTemplatesService instantiationTemplatesService;
@Autowired
public VidController(VidService vidService, AaiService aaiService, RoleProvider roleProvider,
- PombaService pombaService) {
+ PombaService pombaService, InstantiationTemplatesService instantiationTemplatesService) {
this.vidService = vidService;
this.aaiService = aaiService;
this.roleProvider = roleProvider;
this.pombaService = pombaService;
+ this.instantiationTemplatesService = instantiationTemplatesService;
}
/**
@@ -69,8 +74,15 @@ public class VidController extends RestrictedBaseController {
LOG.info("Start API for browse SDC was called");
SecureServices secureServices = new SecureServices();
List<Role> roles = roleProvider.getUserRoles(request);
- secureServices.setServices(aaiService.getServicesByDistributionStatus());
+
+ Collection<Service> servicesByDistributionStatus = aaiService.getServicesByDistributionStatus();
+
+ Collection<Service> servicesWithTemplatesIndication =
+ instantiationTemplatesService.setOnEachServiceIsTemplateExists(servicesByDistributionStatus);
+
+ secureServices.setServices(servicesWithTemplatesIndication);
secureServices.setReadOnly(roleProvider.userPermissionIsReadOnly(roles));
+
return secureServices;
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt
index e46a24f78..063ef6e53 100644
--- a/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt
+++ b/vid-app-common/src/main/java/org/onap/vid/job/command/MsoRequestBuilder.kt
@@ -11,11 +11,12 @@ import org.onap.vid.changeManagement.RequestDetailsWrapper
import org.onap.vid.model.serviceInstantiation.*
import org.onap.vid.mso.model.*
import org.onap.vid.mso.model.BaseResourceInstantiationRequestDetails.*
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue
import org.onap.vid.mso.rest.SubscriberInfo
import org.onap.vid.properties.Features
import org.onap.vid.services.AsyncInstantiationBusinessLogic
import org.onap.vid.services.CloudOwnerService
-import org.onap.vid.utils.JACKSON_OBJECT_MAPPER
+import org.onap.vid.services.UserParamsContainer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.togglz.core.manager.FeatureManager
@@ -108,7 +109,7 @@ class MsoRequestBuilder
//cloud configuration
val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
- val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
+ val userParams = UserParamsContainer(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
//related instance list
val relatedInstanceList = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo))
@@ -118,7 +119,7 @@ class MsoRequestBuilder
relatedInstanceList.add(RelatedInstance(volumeGroupModel, vgInstanceId, vfModuleDetails.volumeGroupInstanceName))
}
- return RequestDetailsWrapper(VfModuleOrVolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters(userParams)))
+ return RequestDetailsWrapper(VfModuleOrVolumeGroupRequestDetails(vfModuleDetails.modelInfo, cloudConfiguration, requestInfo, relatedInstanceList, requestParameters(userParams.toALaCarte())))
}
fun generateVfModuleInstantiationRequest(
@@ -153,8 +154,8 @@ class MsoRequestBuilder
fun generateVolumeGroupInstantiationRequest(vfModuleDetails: VfModule, serviceModelInfo: ModelInfo, serviceInstanceId: String, vnfModelInfo: ModelInfo, vnfInstanceId: String, userId: String, testApi: String?): RequestDetailsWrapper<VolumeGroupRequestDetails> {
val requestInfo = generateRequestInfo(vfModuleDetails.volumeGroupInstanceName, ResourceType.VOLUME_GROUP, vfModuleDetails.isRollbackOnFailure, null, userId)
val cloudConfiguration = generateCloudConfiguration(vfModuleDetails.lcpCloudRegionId, vfModuleDetails.tenantId)
- val userParams = aggregateAllInstanceParams(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
- val requestParameters = RequestParametersVfModuleOrVolumeGroupInstantiation(userParams, vfModuleDetails.isUsePreload, testApi)
+ val userParams = UserParamsContainer(extractActualInstanceParams(vfModuleDetails.instanceParams), vfModuleDetails.supplementaryParams)
+ val requestParameters = RequestParametersVfModuleOrVolumeGroupInstantiation(userParams.toALaCarte(), vfModuleDetails.isUsePreload, testApi)
val relatedInstances = generateRelatedInstances(mapOf(serviceInstanceId to serviceModelInfo, vnfInstanceId to vnfModelInfo))
vfModuleDetails.modelInfo.modelType = "volumeGroup"
@@ -283,39 +284,17 @@ class MsoRequestBuilder
private fun convertVfModuleMapToList(vfModules: Map<String, Map<String, VfModule>>): List<VfModuleMacro> {
return vfModules.values.stream().flatMap { vfModule ->
vfModule.values.stream().map { item ->
- val aggregatedParams = aggregateAllInstanceParams(extractActualInstanceParams(item.instanceParams), item.supplementaryParams)
- val aggregatedParamsConverted = JACKSON_OBJECT_MAPPER.convertValue(aggregatedParams, List::class.java)
+ val userParams = UserParamsContainer(extractActualInstanceParams(item.instanceParams), item.supplementaryParams)
VfModuleMacro(
item.modelInfo,
item.instanceName,
item.volumeGroupInstanceName,
- aggregatedParamsConverted as List<Map<String, String>>)
+ userParams.toMacroPost1806())
}
}.collect(Collectors.toList<VfModuleMacro>())
}
- fun aggregateAllInstanceParams(instanceParams: Map<String, String>?, supplementaryParams: Map<String, String>?): List<UserParamMap<String, String>> {
- var instanceParamsFinal: Map<String, String> = instanceParams ?: emptyMap()
- val supplementaryParamsFinal: Map<String, String> = supplementaryParams ?: emptyMap()
-
- if (!(instanceParamsFinal.isEmpty() && supplementaryParamsFinal.isEmpty())) {
- //remove duplicate keys from instanceParams if exist in supplementaryParams
- instanceParamsFinal = instanceParamsFinal.entries.stream()
- .filter { m -> !supplementaryParamsFinal.containsKey(m.key) }
- .collect(Collectors.toMap({ it.key }, { it.value }))
-
- //aggregate the 2 collections and format them as UserParamMap
- val aggregatedParams = UserParamMap<String, String>()
- aggregatedParams.putAll(instanceParamsFinal)
- aggregatedParams.putAll(supplementaryParamsFinal)
-
- return mutableListOf(aggregatedParams)
- }
-
- return emptyList()
- }
-
//Make sure we always get a one Map from InstanceParams
private fun extractActualInstanceParams(originalInstanceParams: List<MutableMap<String, String>>?): MutableMap<String, String> {
return if (originalInstanceParams.isNullOrEmpty() || originalInstanceParams[0].isNullOrEmpty()) {
@@ -394,14 +373,14 @@ class MsoRequestBuilder
}
}
- private fun generateUserParamList(): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> {
+ private fun generateUserParamList(): List<UserParamNameAndValue> {
return emptyList()
}
fun generateMacroServicePre1806InstantiationRequest(payload: ServiceInstantiation, userId: String): RequestDetailsWrapper<ServiceInstantiationRequestDetails> {
val requestInfo = ServiceInstantiationRequestDetails.RequestInfo(payload.instanceName, payload.productFamilyId, VID_SOURCE, payload.isRollbackOnFailure, userId)
- val userParams = generateUserParamsNameAndValue(payload.instanceParams)
- val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, userParams)
+ val userParams = UserParamsContainer(generateSingleMapFromInstanceParams(payload.instanceParams), emptyList())
+ val requestParameters = ServiceInstantiationRequestDetails.RequestParameters(payload.subscriptionServiceType, false, userParams.toMacroPre1806())
val subscriberInfo = generateSubscriberInfoPre1806(payload)
val project = if (payload.projectName != null) ServiceInstantiationRequestDetails.Project(payload.projectName) else null
val owningEntity = ServiceInstantiationRequestDetails.ServiceInstantiationOwningEntity(payload.owningEntityId, payload.owningEntityName)
@@ -419,8 +398,8 @@ class MsoRequestBuilder
relatedInstanceList))
}
- private fun generateUserParamsNameAndValue(instanceParams: List<Map<String, String>>): List<ServiceInstantiationRequestDetails.UserParamNameAndValue> {
- return instanceParams.getOrElse(0) {emptyMap()}.map{ x-> ServiceInstantiationRequestDetails.UserParamNameAndValue(x.key, x.value)}
+ private fun generateSingleMapFromInstanceParams(instanceParams: List<Map<String, String>>): Map<String, String> {
+ return if (instanceParams.isNullOrEmpty()) emptyMap() else instanceParams[0]
}
private fun generateSubscriberInfoPre1806(payload: ServiceInstantiation): SubscriberInfo {
diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt
index 731625c53..68c9f53e1 100644
--- a/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt
+++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VfmoduleCommand.kt
@@ -207,9 +207,6 @@ class VfmoduleCommand @Autowired constructor(
val serviceModelInfo = serviceModelInfoFromRequest()
val modelNewestUuid = commandUtils.getNewestModelUuid(serviceModelInfo.modelInvariantId);
- check(!modelNewestUuid.equals(serviceModelInfo.modelVersionId, true)) {
- "Model version id ${serviceModelInfo.modelVersionId} is already the latest version of model's invariant id ${serviceModelInfo.modelInvariantId}" }
-
val serviceNewestModel = commandUtils.getServiceModel(modelNewestUuid);
return serviceNewestModel;
diff --git a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt
index 48ff7b7ac..b008c1306 100644
--- a/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt
+++ b/vid-app-common/src/main/java/org/onap/vid/job/command/VnfCommand.kt
@@ -12,6 +12,7 @@ import org.onap.vid.model.serviceInstantiation.Vnf
import org.onap.vid.mso.RestMsoImplementation
import org.onap.vid.properties.Features
import org.onap.vid.services.AsyncInstantiationBusinessLogic
+import org.onap.vid.utils.isNotActive
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.context.annotation.Scope
@@ -59,9 +60,9 @@ class VnfCommand @Autowired constructor(
val vfModules:List<VfModule> = request.vfModules.values.stream().flatMap { vfKey -> vfKey.values.stream() }.collect(Collectors.toList<VfModule>())
try {
- childJobs = pushChildrenJobsToBroker(vfModules.filter { filterModuleByNeedToCreateBase(it) }, dataForChild, JobType.VolumeGroupInstantiation)
+ childJobs = pushChildrenJobsToBroker(vfModulesForChildrenJobs(vfModules), dataForChild, JobType.VolumeGroupInstantiation)
} catch (e: AsdcCatalogException) {
- LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message , e)
+ LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to retrieve service definitions from SDC, for VfModule is BaseModule.. Error: " + e.message, e)
//return Job.JobStatus.FAILED
throw e;
}
@@ -70,11 +71,26 @@ class VnfCommand @Autowired constructor(
return Job.JobStatus.COMPLETED_WITH_NO_ACTION
}
- private fun filterModuleByNeedToCreateBase(it: VfModule):Boolean {
+ private fun vfModulesForChildrenJobs(vfModules: List<VfModule>): List<VfModule> =
+ vfModules
+ .filter { filterModuleByNeedToCreateBase(it) }
+ .map { childVfModuleWithVnfRegionAndTenant(it) }
+
+ internal fun childVfModuleWithVnfRegionAndTenant(vfModule: VfModule): VfModule {
+ if (featureManager.isNotActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)) {
+ return vfModule
+ }
+
+ val vnfLcpCloudRegionId = getRequest().lcpCloudRegionId
+ val vnfTenantId = getRequest().tenantId
+ return vfModule.cloneWith(vnfLcpCloudRegionId, vnfTenantId)
+ }
+
+ private fun filterModuleByNeedToCreateBase(vfModule: VfModule): Boolean {
return needToCreateBaseModule ==
- commandUtils.isVfModuleBaseModule(
- serviceModelInfoFromRequest().modelVersionId,
- it.modelInfo.modelVersionId)
+ commandUtils.isVfModuleBaseModule(
+ serviceModelInfoFromRequest().modelVersionId,
+ vfModule.modelInfo.modelVersionId)
}
override fun planCreateMyselfRestCall(commandParentData: CommandParentData, request: JobAdapter.AsyncJobRequest, userId: String, testApi: String?): MsoRestCallPlan {
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/ExceptionResponse.java b/vid-app-common/src/main/java/org/onap/vid/model/ExceptionResponse.java
index d2e5d637e..f8d5918db 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/ExceptionResponse.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/ExceptionResponse.java
@@ -20,10 +20,9 @@
package org.onap.vid.model;
+import org.onap.logging.ref.slf4j.ONAPLogConstants.MDCs;
import org.slf4j.MDC;
-import static com.att.eelf.configuration.Configuration.MDC_KEY_REQUEST_ID;
-
/**
* The Class ExceptionResponse.
*/
@@ -67,7 +66,7 @@ public class ExceptionResponse {
public void setException(Exception exception) {
setException(exception.getClass().toString().replaceFirst("^.*[\\.$]", ""));
- setMessage(exception.getMessage() + " (Request id: " + MDC.get(MDC_KEY_REQUEST_ID) + ")");
+ setMessage(exception.getMessage() + " (Request id: " + MDC.get(MDCs.REQUEST_ID) + ")");
}
/**
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/ServiceInstanceSearchResult.java b/vid-app-common/src/main/java/org/onap/vid/model/ServiceInstanceSearchResult.java
index 259405c4e..f75027994 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/ServiceInstanceSearchResult.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/ServiceInstanceSearchResult.java
@@ -20,11 +20,19 @@
package org.onap.vid.model;
-public class ServiceInstanceSearchResult {
+import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.vid.roles.WithPermissionPropertiesOwningEntity;
+import org.onap.vid.roles.WithPermissionPropertiesSubscriberAndServiceType;
+
+public class ServiceInstanceSearchResult
+ implements WithPermissionPropertiesSubscriberAndServiceType, WithPermissionPropertiesOwningEntity {
+
+ private final String SUBSCRIBER_ID_FRONTEND_ALIAS = "globalCustomerId";
private String serviceInstanceId;
- private String globalCustomerId;
+ private String subscriberId;
private String serviceType;
@@ -36,21 +44,24 @@ public class ServiceInstanceSearchResult {
private String aaiModelVersionId;
+ private String owningEntityId;
+
private boolean isPermitted;
public ServiceInstanceSearchResult(){
-
}
- public ServiceInstanceSearchResult(String serviceInstanceId, String globalCustomerId, String serviceType,
- String serviceInstanceName, String subscriberName, String aaiModelInvariantId,
- String aaiModelVersionId, boolean isPermitted) {
+
+ public ServiceInstanceSearchResult(String serviceInstanceId, String subscriberId, String serviceType,
+ String serviceInstanceName, String subscriberName, String aaiModelInvariantId,
+ String aaiModelVersionId, String owningEntityId, boolean isPermitted) {
this.serviceInstanceId = serviceInstanceId;
- this.globalCustomerId = globalCustomerId;
+ this.subscriberId = subscriberId;
this.serviceType = serviceType;
this.serviceInstanceName = serviceInstanceName;
this.subscriberName = subscriberName;
this.aaiModelInvariantId = aaiModelInvariantId;
this.aaiModelVersionId = aaiModelVersionId;
+ this.owningEntityId = owningEntityId;
this.isPermitted = isPermitted;
}
@@ -62,14 +73,17 @@ public class ServiceInstanceSearchResult {
this.serviceInstanceId = serviceInstanceId;
}
- public String getGlobalCustomerId() {
- return globalCustomerId;
+ @Override
+ @JsonProperty(SUBSCRIBER_ID_FRONTEND_ALIAS)
+ public String getSubscriberId() {
+ return subscriberId;
}
- public void setGlobalCustomerId(String globalCustomerId) {
- this.globalCustomerId = globalCustomerId;
+ public void setSubscriberId(String subscriberId) {
+ this.subscriberId = subscriberId;
}
+ @Override
public String getServiceType() {
return serviceType;
}
@@ -110,6 +124,15 @@ public class ServiceInstanceSearchResult {
this.aaiModelVersionId = aaiModelVersionId;
}
+ @Override
+ public String getOwningEntityId() {
+ return owningEntityId;
+ }
+
+ public void setOwningEntityId(String owningEntityId) {
+ this.owningEntityId = owningEntityId;
+ }
+
public boolean getIsPermitted() {
return isPermitted;
}
@@ -119,21 +142,21 @@ public class ServiceInstanceSearchResult {
}
@Override
- public boolean equals(Object other){
- if (other instanceof ServiceInstanceSearchResult) {
- ServiceInstanceSearchResult serviceInstanceSearchResultOther = (ServiceInstanceSearchResult) other;
- if (this.getServiceInstanceId().equals(serviceInstanceSearchResultOther.getServiceInstanceId())) {
- return true;
- }
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
}
- return false;
+ ServiceInstanceSearchResult that = (ServiceInstanceSearchResult) o;
+
+ return StringUtils.equals(serviceInstanceId, that.serviceInstanceId);
}
@Override
public int hashCode() {
- int result = 17;
- result = 31 * result + serviceInstanceId.hashCode();
- return result;
+ return serviceInstanceId != null ? serviceInstanceId.hashCode() : 0;
}
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/BaseResource.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/BaseResource.java
index 1079fbe92..7617d7778 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/BaseResource.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/BaseResource.java
@@ -20,20 +20,22 @@
package org.onap.vid.model.serviceInstantiation;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.ImmutableMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobType;
import org.onap.vid.model.Action;
import org.onap.vid.mso.model.ModelInfo;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
public abstract class BaseResource implements JobAdapter.AsyncJobRequest {
protected String instanceId;
@@ -60,6 +62,9 @@ public abstract class BaseResource implements JobAdapter.AsyncJobRequest {
protected Integer position;
+ @JsonInclude(NON_NULL)
+ protected String originalName; //not used at backend, but stored for fronted
+
private static final Map<String, Action> actionStingToEnumMap = ImmutableMap.<String, Action>builder()
.put("Delete", Action.Delete)
@@ -85,7 +90,8 @@ public abstract class BaseResource implements JobAdapter.AsyncJobRequest {
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
this.modelInfo = modelInfo;
this.modelInfo.setModelType(getModelType());
this.rollbackOnFailure = rollbackOnFailure;
@@ -99,6 +105,7 @@ public abstract class BaseResource implements JobAdapter.AsyncJobRequest {
this.isFailed = isFailed!= null ? isFailed: false;
this.statusMessage = statusMessage;
this.position = position;
+ this.originalName = originalName;
}
private Action actionStringToEnum(String actionAsString) {
@@ -177,6 +184,10 @@ public abstract class BaseResource implements JobAdapter.AsyncJobRequest {
this.position = position;
}
+ public String getOriginalName() {
+ return originalName;
+ }
+
@JsonIgnore
public abstract Collection<? extends BaseResource> getChildren();
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroup.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroup.java
index f23c2e73e..642e28b36 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroup.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroup.java
@@ -21,13 +21,12 @@
package org.onap.vid.model.serviceInstantiation;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.onap.vid.job.JobAdapter;
-import org.onap.vid.job.JobType;
-import org.onap.vid.mso.model.ModelInfo;
-
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
+import org.onap.vid.job.JobAdapter;
+import org.onap.vid.job.JobType;
+import org.onap.vid.mso.model.ModelInfo;
public class InstanceGroup extends BaseResource implements JobAdapter.AsyncJobRequest {
@@ -42,10 +41,11 @@ public class InstanceGroup extends BaseResource implements JobAdapter.AsyncJobRe
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, null, null, null, null, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.vnfGroupMembers = vnfGroupMembers;
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroupMember.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroupMember.java
index e9f34ccfb..758ee0694 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroupMember.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/InstanceGroupMember.java
@@ -34,9 +34,10 @@ public class InstanceGroupMember extends BaseResource implements JobAdapter.Asyn
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(new ModelInfo(), null, action, null, null, null, null, false, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
}
@Override
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Network.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Network.java
index b9a0aeb85..cec61f6b7 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Network.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Network.java
@@ -21,14 +21,13 @@
package org.onap.vid.model.serviceInstantiation;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.onap.vid.job.JobAdapter;
-import org.onap.vid.job.JobType;
-import org.onap.vid.mso.model.ModelInfo;
-
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.onap.vid.job.JobAdapter;
+import org.onap.vid.job.JobType;
+import org.onap.vid.mso.model.ModelInfo;
public class Network extends BaseResource implements JobAdapter.AsyncJobRequest {
@@ -53,10 +52,11 @@ public class Network extends BaseResource implements JobAdapter.AsyncJobRequest
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.productFamilyId = productFamilyId;
this.platformName = platformName;
this.lineOfBusiness = lineOfBusiness;
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java
index e7e5783c4..7c04a91dc 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiation.java
@@ -104,9 +104,10 @@ public class ServiceInstantiation extends BaseResource implements JobAdapter.Asy
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("vidNotions") VidNotions vidNotions) {
+ @JsonProperty("vidNotions") VidNotions vidNotions,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- null);
+ null, originalName);
this.owningEntityId = owningEntityId;
this.owningEntityName = owningEntityName;
this.projectName = projectName;
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java
index 4872ce2c8..9499beb50 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/ServiceInstantiationTemplate.java
@@ -52,7 +52,8 @@ public class ServiceInstantiationTemplate extends ServiceInstantiation implement
baseService.isRollbackOnFailure(), baseService.isALaCarte(), baseService.getTestApi(),
baseService.getInstanceId(), Objects.toString(baseService.getAction(), null),
baseService.getTrackById(), baseService.getIsFailed(), baseService.getStatusMessage(),
- baseService.getVidNotions()
+ baseService.getVidNotions(),
+ baseService.getOriginalName()
);
this.existingVNFCounterMap = vnfCounterMap;
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java
index 89e25e662..79ea7f147 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/VfModule.java
@@ -33,6 +33,7 @@ import javax.annotation.Nullable;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobType;
import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
/**
* The Class VfModule.
@@ -42,7 +43,7 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest
@JsonInclude(NON_NULL) @JsonProperty("volumeGroupName") private final String volumeGroupInstanceName;
@JsonInclude(NON_NULL) @JsonProperty("sdncPreLoad") private Boolean usePreload;
- private Map<String, String> supplementaryParams;
+ private List<UserParamNameAndValue> supplementaryParams;
@JsonInclude(NON_NULL)
private final Boolean retainVolumeGroups;
@@ -58,7 +59,7 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest
@JsonProperty("legacyRegion") String legacyRegion,
@JsonProperty("tenantId") String tenantId,
@JsonProperty("instanceParams") List<Map<String, String>> instanceParams,
- @JsonProperty("supplementaryFileContent") Map<String, String> supplementaryParams,
+ @JsonProperty("supplementaryFileContent") List<UserParamNameAndValue> supplementaryParams,
@JsonProperty("rollbackOnFailure") boolean rollbackOnFailure,
@JsonProperty("sdncPreLoad") @JsonAlias("usePreload") Boolean usePreload,
@JsonProperty("instanceId") String instanceId,
@@ -67,9 +68,10 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest
@JsonProperty("statusMessage") String statusMessage,
@Nullable @JsonProperty("retainAssignments") Boolean retainAssignments,
@Nullable @JsonProperty("retainVolumeGroups") Boolean retainVolumeGroups,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.volumeGroupInstanceName = volumeGroupInstanceName;
this.usePreload = usePreload;
this.supplementaryParams = supplementaryParams;
@@ -86,7 +88,7 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest
return usePreload;
}
- public Map<String, String> getSupplementaryParams() {
+ public List<UserParamNameAndValue> getSupplementaryParams() {
return supplementaryParams;
}
@@ -134,6 +136,32 @@ public class VfModule extends BaseResource implements JobAdapter.AsyncJobRequest
this.getStatusMessage(),
this.isRetainAssignments(),
this.isRetainVolumeGroups(),
- this.getPosition());
+ this.getPosition(),
+ this.getOriginalName()
+ );
+ }
+
+ public VfModule cloneWith(String lcpCloudRegionId, String tenantId) {
+ return new VfModule(
+ this.getModelInfo(),
+ this.getInstanceName(),
+ this.getVolumeGroupInstanceName(),
+ this.getAction().toString(),
+ lcpCloudRegionId,
+ lcpCloudRegionId,
+ tenantId,
+ this.getInstanceParams(),
+ this.getSupplementaryParams(),
+ this.isRollbackOnFailure(),
+ this.isUsePreload(),
+ this.getInstanceId(),
+ this.getTrackById(),
+ this.getIsFailed(),
+ this.getStatusMessage(),
+ this.isRetainAssignments(),
+ this.isRetainVolumeGroups(),
+ this.getPosition(),
+ this.getOriginalName()
+ );
}
} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Vnf.java b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Vnf.java
index fc71f279f..2ed219637 100644
--- a/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Vnf.java
+++ b/vid-app-common/src/main/java/org/onap/vid/model/serviceInstantiation/Vnf.java
@@ -21,15 +21,18 @@
package org.onap.vid.model.serviceInstantiation;
+import static java.util.stream.Collectors.toList;
+
import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobType;
import org.onap.vid.mso.model.ModelInfo;
-import java.util.*;
-
-import static java.util.stream.Collectors.toList;
-
/**
* The Class VNF.
*/
@@ -59,10 +62,11 @@ public class Vnf extends BaseResource implements JobAdapter.AsyncJobRequest {
@JsonProperty("trackById") String trackById,
@JsonProperty("isFailed") Boolean isFailed,
@JsonProperty("statusMessage") String statusMessage,
- @JsonProperty("position") Integer position) {
+ @JsonProperty("position") Integer position,
+ @JsonProperty("originalName") String originalName) {
super(modelInfo, instanceName, action, lcpCloudRegionId, legacyRegion, tenantId, instanceParams, rollbackOnFailure, instanceId, trackById, isFailed, statusMessage,
- position);
+ position, originalName);
this.productFamilyId = productFamilyId;
this.platformName = platformName;
this.lineOfBusiness = lineOfBusiness;
diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/MsoUtil.java b/vid-app-common/src/main/java/org/onap/vid/mso/MsoUtil.java
index 626816f7f..8de534a8e 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/MsoUtil.java
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/MsoUtil.java
@@ -21,15 +21,15 @@
package org.onap.vid.mso;
+import static org.apache.commons.lang3.StringUtils.firstNonBlank;
+import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
-import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
import io.joshworks.restclient.http.HttpResponse;
import java.io.IOException;
-import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.onap.vid.exceptions.GenericUncheckedException;
public class MsoUtil {
@@ -76,22 +76,31 @@ public class MsoUtil {
}
public static String formatExceptionAdditionalInfo(int statusCode, String msoResponse) {
- String errorMsg = "Http Code:" + statusCode;
- if (!StringUtils.isEmpty(msoResponse)) {
- String filteredJson;
- try {
- filteredJson = StringUtils.defaultIfEmpty(
- JACKSON_OBJECT_MAPPER.readTree(msoResponse).path("serviceException").toString().replaceAll("[\\{\\}]","") ,
- msoResponse
- );
- } catch (JsonParseException e) {
- filteredJson = msoResponse;
- } catch (IOException e) {
- throw new GenericUncheckedException(e);
- }
+ final String errorMsg = "Http Code:" + statusCode;
+
+ if (isEmpty(msoResponse)) {
+ return errorMsg;
+ }
+
+ try {
+ JsonNode jsonNode = JACKSON_OBJECT_MAPPER.readTree(msoResponse);
- errorMsg = errorMsg + ", " + filteredJson;
+ return errorMsg + ", " + firstNonBlank(
+ removeBraces(jsonNode.get("serviceException")),
+ removeBraces(jsonNode.path("requestError").get("serviceException")),
+ msoResponse
+ );
+
+ } catch (Exception e) {
+ return errorMsg + ", " + msoResponse;
}
- return errorMsg;
+ }
+
+ private static String removeBraces(JsonNode jsonNode) {
+ if (jsonNode == null || jsonNode.isMissingNode()) {
+ return null;
+ }
+
+ return jsonNode.toString().replaceAll("[\\{\\}]", "");
}
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/model/ServiceInstantiationRequestDetails.java b/vid-app-common/src/main/java/org/onap/vid/mso/model/ServiceInstantiationRequestDetails.java
index e610d6c40..acbf778ea 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/model/ServiceInstantiationRequestDetails.java
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/model/ServiceInstantiationRequestDetails.java
@@ -20,15 +20,16 @@
package org.onap.vid.mso.model;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY;
+import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
-import org.onap.vid.mso.rest.SubscriberInfo;
-
import java.util.List;
import java.util.Map;
-
-import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY;
-import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
+import java.util.Objects;
+import org.onap.vid.mso.rest.SubscriberInfo;
public class ServiceInstantiationRequestDetails {
@@ -122,7 +123,11 @@ public class ServiceInstantiationRequestDetails {
private final String name;
private final String value;
- public UserParamNameAndValue(String name, String value) {
+ @JsonCreator
+ public UserParamNameAndValue(
+ @JsonProperty("name") String name,
+ @JsonProperty("value") String value
+ ) {
this.name = name;
this.value = value;
}
@@ -134,6 +139,24 @@ public class ServiceInstantiationRequestDetails {
public String getValue() {
return value;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof UserParamNameAndValue)) {
+ return false;
+ }
+ UserParamNameAndValue that = (UserParamNameAndValue) o;
+ return Objects.equals(getName(), that.getName()) &&
+ Objects.equals(getValue(), that.getValue());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getName(), getValue());
+ }
}
public static class HomingSolution implements UserParamTypes {
diff --git a/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt b/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt
index bba4081dd..bf9e41ad9 100644
--- a/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt
+++ b/vid-app-common/src/main/java/org/onap/vid/mso/model/VfModuleOrVolumeGroupRequestDetails.kt
@@ -103,7 +103,7 @@ data class VfModuleOrVolumeGroupRequestDetails(
open class RequestParametersVfModuleOrVolumeGroup internal constructor(
userParams: List<UserParamTypes>,
- @get:JsonInclude(NON_NULL) val isUsePreload: Boolean?,
+ val isUsePreload: Boolean,
testApi: String?
) : BaseResourceInstantiationRequestDetails.RequestParameters(userParams, testApi)
@@ -111,7 +111,7 @@ class RequestParametersVfModuleOrVolumeGroupInstantiation(
userParams: List<UserParamTypes>,
usePreload: Boolean?,
testApi: String?
-) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload, testApi)
+) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload.orFalse(), testApi)
class RequestParametersVfModuleUpgrade(
userParams: List<UserParamTypes>,
@@ -119,7 +119,8 @@ class RequestParametersVfModuleUpgrade(
testApi: String?,
@get:JsonInclude(NON_NULL) val retainAssignments: Boolean?,
@get:JsonInclude(NON_NULL) val rebuildVolumeGroups: Boolean?
-) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload, testApi)
+) : RequestParametersVfModuleOrVolumeGroup(userParams, usePreload.orFalse(), testApi)
class UserParamMap<K, V> : HashMap<K, V>(), UserParamTypes, MutableMap<K, V>
+private fun Boolean?.orFalse(): Boolean = this ?: false
diff --git a/vid-app-common/src/main/java/org/onap/vid/properties/FeatureSetsManager.kt b/vid-app-common/src/main/java/org/onap/vid/properties/FeatureSetsManager.kt
new file mode 100644
index 000000000..207bde7aa
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/properties/FeatureSetsManager.kt
@@ -0,0 +1,82 @@
+package org.onap.vid.properties
+
+import org.apache.commons.io.filefilter.WildcardFileFilter
+import org.springframework.web.context.request.RequestContextHolder.getRequestAttributes
+import org.springframework.web.context.request.ServletRequestAttributes
+import org.togglz.core.Feature
+import org.togglz.core.manager.FeatureManager
+import org.togglz.core.manager.FeatureManagerBuilder
+import org.togglz.core.repository.file.FileBasedStateRepository
+import java.io.File
+import java.io.FilenameFilter
+import javax.servlet.ServletContext
+import javax.servlet.http.HttpServletRequest
+
+
+private const val SLOW_RELOAD = 60_000
+private const val COOKIE_NAME = "features.set"
+
+class FeatureSetsManager(
+ private val defaultManager: FeatureManager,
+ private val nameProvider: AlternativeFeatureSetNameProvider,
+ private val servletContext: ServletContext
+) : FeatureManager by defaultManager {
+
+ override fun isActive(feature: Feature?): Boolean {
+ return resolvedFeatureManager().isActive(feature)
+ }
+
+ private fun resolvedFeatureManager(): FeatureManager {
+ return when (val alternativeFeatureSetName = nameProvider.alternativeFeatureSetName) {
+ null -> defaultManager
+ else -> allFeatureManagers.getValue(alternativeFeatureSetName)
+ }
+ }
+
+ internal val allFeatureManagers: Map<String, FeatureManager> by lazy {
+ allFeatureSetFiles().associateBy(
+ { it.name },
+ { newFeatureManager(it) }
+ ).withDefault { allFeaturesOff }
+ }
+
+ private val allFeaturesOff =
+ FeatureManagerBuilder().featureEnum(Features::class.java).build()
+
+ private fun newFeatureManager(file: File): FeatureManager {
+ return FeatureManagerBuilder()
+ .featureEnum(Features::class.java)
+ .stateRepository(FileBasedStateRepository(file, SLOW_RELOAD))
+ .build()
+ }
+
+ private fun allFeatureSetFiles(): Array<File> {
+ val dir = File(servletContext.getRealPath("/WEB-INF/conf/"))
+ val fileFilter: FilenameFilter = WildcardFileFilter("*.features.properties")
+
+ return dir.listFiles(fileFilter) ?: emptyArray()
+ }
+}
+
+interface AlternativeFeatureSetNameProvider {
+ val alternativeFeatureSetName: String?
+}
+
+class AlternativeFeatureSetNameFromCookie: AlternativeFeatureSetNameProvider {
+ override val alternativeFeatureSetName: String?
+ get() = valueFromCookie(currentHttpRequest())
+
+ internal fun valueFromCookie(httpServletRequest: HttpServletRequest?): String? {
+ return httpServletRequest
+ ?.cookies
+ ?.firstOrNull { it.name == COOKIE_NAME }
+ ?.value
+ }
+
+ internal fun currentHttpRequest(): HttpServletRequest? {
+ return when (val requestAttributes = getRequestAttributes()) {
+ is ServletRequestAttributes -> requestAttributes.request
+ else -> null
+ }
+ }
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
index a42110337..cc3fad65e 100644
--- a/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
+++ b/vid-app-common/src/main/java/org/onap/vid/properties/Features.java
@@ -81,9 +81,13 @@ public enum Features implements Feature {
FLAG_2002_IDENTIFY_INVARIANT_MACRO_UUID_BY_BACKEND,
FLAG_2004_INSTANTIATION_STATUS_FILTER,
FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE,
- FLAG_2004_TEMP_BUTTON_TO_INSTANTIATION_STATUS_FILTER,
FLAG_2004_INSTANTIATION_TEMPLATES_POPUP,
+ FLAG_2006_VFM_SDNC_PRELOAD_FILES,
FLAG_2002_UNLIMITED_MAX,
+ FLAG_MORE_AUDIT_INFO_LINK_ON_AUDIT_INFO,
+ FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY,
+ FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF,
+
;
diff --git a/vid-app-common/src/main/java/org/onap/vid/properties/FeaturesTogglingConfiguration.java b/vid-app-common/src/main/java/org/onap/vid/properties/FeaturesTogglingConfiguration.java
index 4d4387d4e..96331b7c4 100644
--- a/vid-app-common/src/main/java/org/onap/vid/properties/FeaturesTogglingConfiguration.java
+++ b/vid-app-common/src/main/java/org/onap/vid/properties/FeaturesTogglingConfiguration.java
@@ -20,6 +20,8 @@
package org.onap.vid.properties;
+import java.io.File;
+import javax.servlet.ServletContext;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
@@ -30,9 +32,6 @@ import org.togglz.core.manager.FeatureManagerBuilder;
import org.togglz.core.repository.file.FileBasedStateRepository;
import org.togglz.spring.listener.TogglzApplicationContextBinderApplicationListener;
-import javax.servlet.ServletContext;
-import java.io.File;
-
@Configuration
public class FeaturesTogglingConfiguration {
@Bean
@@ -52,11 +51,13 @@ public class FeaturesTogglingConfiguration {
filename = StringUtils.trimToNull(filename);
- return new FeatureManagerBuilder()
+ return new FeatureSetsManager(
+ new FeatureManagerBuilder()
.featureEnum(Features.class)
.stateRepository(new FileBasedStateRepository(
- new File(filename.startsWith("/")? filename : servletContext.getRealPath("/WEB-INF/conf/" + filename))
+ new File(filename.startsWith("/") ? filename : servletContext.getRealPath("/WEB-INF/conf/" + filename))
))
- .build();
+ .build(), new AlternativeFeatureSetNameFromCookie(), servletContext
+ );
}
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/AlwaysValidRoleValidator.java b/vid-app-common/src/main/java/org/onap/vid/roles/AlwaysValidRoleValidator.java
index 4e5340fc2..66eab1810 100644
--- a/vid-app-common/src/main/java/org/onap/vid/roles/AlwaysValidRoleValidator.java
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/AlwaysValidRoleValidator.java
@@ -27,17 +27,17 @@ public class AlwaysValidRoleValidator implements RoleValidator {
}
@Override
- public boolean isSubscriberPermitted(String subscriberName) {
+ public boolean isSubscriberPermitted(String subscriberId) {
return true;
}
@Override
- public boolean isServicePermitted(String subscriberName, String serviceType) {
+ public boolean isServicePermitted(WithPermissionProperties permissionProperties) {
return true;
}
@Override
- public boolean isTenantPermitted(String globalCustomerId, String serviceType, String tenantName) {
+ public boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName) {
return true;
}
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/PermissionProperties.kt b/vid-app-common/src/main/java/org/onap/vid/roles/PermissionProperties.kt
new file mode 100644
index 000000000..dbdd41326
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/PermissionProperties.kt
@@ -0,0 +1,34 @@
+package org.onap.vid.roles
+
+import org.onap.vid.aai.ServiceSubscription
+
+
+interface WithPermissionProperties
+
+interface WithPermissionPropertiesSubscriberAndServiceType: WithPermissionProperties {
+ val subscriberId: String?
+ val serviceType: String?
+}
+
+interface WithPermissionPropertiesOwningEntity: WithPermissionProperties {
+ val owningEntityId: String?
+}
+
+
+data class AllPermissionProperties(
+ override val subscriberId: String?,
+ override val serviceType: String?,
+ override val owningEntityId: String?
+): WithPermissionPropertiesOwningEntity, WithPermissionPropertiesSubscriberAndServiceType
+
+data class PermissionPropertiesOwningEntity(
+ override val owningEntityId: String?
+): WithPermissionPropertiesOwningEntity
+
+data class PermissionPropertiesSubscriberAndServiceType(
+ override val subscriberId: String?,
+ override val serviceType: String?
+) : WithPermissionPropertiesSubscriberAndServiceType {
+ constructor(serviceSubscription: ServiceSubscription, subscriberId: String?) : this(subscriberId, serviceSubscription.serviceType)
+}
+
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/Role.java b/vid-app-common/src/main/java/org/onap/vid/roles/Role.java
index 454483031..3de894480 100644
--- a/vid-app-common/src/main/java/org/onap/vid/roles/Role.java
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/Role.java
@@ -20,49 +20,44 @@
package org.onap.vid.roles;
-/**
- * Created by Oren on 7/1/17.
- */
-
public class Role {
- private EcompRole ecompRole;
+ private final EcompRole ecompRole;
+
+ private final String subscriberId;
- private String subscribeName;
+ private final String serviceType;
- private String serviceType;
+ private final String tenant;
- private String tenant;
+ private final String owningEntityId;
- public Role(EcompRole ecompRole, String subscribeName, String serviceType, String tenant) {
+ public Role(EcompRole ecompRole, String subscriberId, String serviceType, String tenant, String owningEntityId) {
this.ecompRole = ecompRole;
- this.subscribeName = subscribeName;
+ this.subscriberId = subscriberId;
this.serviceType = serviceType;
this.tenant = tenant;
+ this.owningEntityId = owningEntityId;
}
public EcompRole getEcompRole() {
return ecompRole;
}
-
- public String getSubscribeName() {
- return subscribeName;
- }
-
- public void setSubscribeName(String subscribeName) {
- this.subscribeName = subscribeName;
+ public String getSubscriberId() {
+ return subscriberId;
}
public String getServiceType() {
return serviceType;
}
-
public String getTenant() {
return tenant;
}
-
+ public String getOwningEntityId() {
+ return owningEntityId;
+ }
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleProvider.java b/vid-app-common/src/main/java/org/onap/vid/roles/RoleProvider.java
index 898db332c..c35f5f704 100644
--- a/vid-app-common/src/main/java/org/onap/vid/roles/RoleProvider.java
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleProvider.java
@@ -42,11 +42,6 @@ import org.onap.vid.services.AaiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-
-/**
- * Created by Oren on 7/1/17.
- */
-
@Component
public class RoleProvider {
@@ -58,16 +53,20 @@ public class RoleProvider {
private Function<HttpServletRequest, Integer> getUserIdFunction;
private Function<HttpServletRequest, Map> getRolesFunction;
+ private final RoleValidatorFactory roleValidatorFactory;
@Autowired
- public RoleProvider(AaiService aaiService) {
+ public RoleProvider(AaiService aaiService, RoleValidatorFactory roleValidatorFactory) {
this.aaiService=aaiService;
+ this.roleValidatorFactory = roleValidatorFactory;
getUserIdFunction = UserUtils::getUserId;
getRolesFunction = UserUtils::getRoles;
}
- RoleProvider(AaiService aaiService, Function<HttpServletRequest, Integer> getUserIdFunction, Function<HttpServletRequest, Map> getRolesFunction) {
+ RoleProvider(AaiService aaiService, RoleValidatorFactory roleValidatorFactory,
+ Function<HttpServletRequest, Integer> getUserIdFunction, Function<HttpServletRequest, Map> getRolesFunction) {
this.aaiService = aaiService;
+ this.roleValidatorFactory = roleValidatorFactory;
this.getRolesFunction = getRolesFunction;
this.getUserIdFunction = getUserIdFunction;
}
@@ -143,11 +142,13 @@ public class RoleProvider {
public Role createRoleFromStringArr(String[] roleParts, String rolePrefix) throws RoleParsingException {
String globalCustomerID = replaceSubscriberNameToGlobalCustomerID(roleParts[0], rolePrefix);
+ String owningEntityId = translateOwningEntityNameToOwningEntityId(roleParts[0]);
+
try {
if (roleParts.length > 2) {
- return new Role(EcompRole.READ, globalCustomerID, roleParts[1], roleParts[2]);
+ return new Role(EcompRole.READ, globalCustomerID, roleParts[1], roleParts[2], owningEntityId);
} else {
- return new Role(EcompRole.READ, globalCustomerID, roleParts[1], null);
+ return new Role(EcompRole.READ, globalCustomerID, roleParts[1], null, owningEntityId);
}
} catch (ArrayIndexOutOfBoundsException e) {
if (roleParts.length > 0)
@@ -161,8 +162,12 @@ public class RoleProvider {
}
+ private String translateOwningEntityNameToOwningEntityId(String owningEntityName) {
+ return owningEntityName; // TODO: translate to id
+ }
+
public RoleValidator getUserRolesValidator(HttpServletRequest request) {
- return RoleValidator.by(getUserRoles(request));
+ return roleValidatorFactory.by(getUserRoles(request));
}
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java
index 830c0f50c..14c027392 100644
--- a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java
@@ -21,26 +21,11 @@
package org.onap.vid.roles;
-import java.util.List;
-import org.apache.commons.lang3.StringUtils;
-import org.onap.portalsdk.core.util.SystemProperties;
-
public interface RoleValidator {
- static RoleValidator by(List<Role> roles) {
- final boolean disableRoles = StringUtils.equals(SystemProperties.getProperty("role_management_activated"), "false");
- return by(roles, disableRoles);
- }
-
- static RoleValidator by(List<Role> roles, boolean disableRoles) {
- return disableRoles
- ? new AlwaysValidRoleValidator()
- : new RoleValidatorByRoles(roles);
- }
-
- boolean isSubscriberPermitted(String subscriberName);
+ boolean isSubscriberPermitted(String subscriberId);
- boolean isServicePermitted(String subscriberName, String serviceType);
+ boolean isServicePermitted(WithPermissionProperties serviceInstanceSearchResult);
- boolean isTenantPermitted(String globalCustomerId, String serviceType, String tenantName);
+ boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName);
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByOwningEntity.java b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByOwningEntity.java
new file mode 100644
index 000000000..8d73dc400
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByOwningEntity.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+
+public class RoleValidatorByOwningEntity implements RoleValidator{
+
+ private final List<Role> userRoles;
+
+ RoleValidatorByOwningEntity(List<Role> roles) {
+ this.userRoles = roles;
+ }
+
+ private boolean isOwningEntityIdPermitted(String owningEntityId) {
+ if (StringUtils.isEmpty(owningEntityId)) {
+ return false;
+ }
+
+ return userRoles.stream().anyMatch(userRole ->
+ StringUtils.equals(userRole.getOwningEntityId(), owningEntityId)
+ );
+ }
+
+ @Override
+ public boolean isSubscriberPermitted(String subscriberId) {
+ return false;
+ }
+
+ @Override
+ public boolean isServicePermitted(WithPermissionProperties permissionProperties) {
+ if (permissionProperties instanceof WithPermissionPropertiesOwningEntity) {
+ String owningEntityId = ((WithPermissionPropertiesOwningEntity) permissionProperties).getOwningEntityId();
+ return isOwningEntityIdPermitted(owningEntityId);
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName) {
+ return false;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByRoles.java b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceType.java
index ad5b519c4..24a00f6e8 100644
--- a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorByRoles.java
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceType.java
@@ -21,21 +21,20 @@
package org.onap.vid.roles;
import java.util.List;
-import java.util.Map;
-import org.onap.vid.mso.rest.RequestDetails;
+import org.apache.commons.lang3.StringUtils;
-public class RoleValidatorByRoles implements RoleValidator {
+public class RoleValidatorBySubscriberAndServiceType implements RoleValidator {
private final List<Role> userRoles;
- RoleValidatorByRoles(List<Role> roles) {
+ RoleValidatorBySubscriberAndServiceType(List<Role> roles) {
this.userRoles = roles;
}
@Override
- public boolean isSubscriberPermitted(String subscriberName) {
+ public boolean isSubscriberPermitted(String subscriberId) {
for (Role role : userRoles) {
- if (role.getSubscribeName().equals(subscriberName)) {
+ if (role.getSubscriberId().equals(subscriberId)) {
return true;
}
}
@@ -43,19 +42,26 @@ public class RoleValidatorByRoles implements RoleValidator {
}
@Override
- public boolean isServicePermitted(String subscriberName, String serviceType) {
- for (Role role : userRoles) {
- if (role.getSubscribeName().equals(subscriberName) && role.getServiceType().equals(serviceType)) {
- return true;
- }
+ public boolean isServicePermitted(WithPermissionProperties permissionProperties) {
+ if (permissionProperties instanceof WithPermissionPropertiesSubscriberAndServiceType) {
+ return isServicePermitted(
+ (WithPermissionPropertiesSubscriberAndServiceType) permissionProperties
+ );
}
return false;
}
+ private boolean isServicePermitted(WithPermissionPropertiesSubscriberAndServiceType permissionProperties) {
+ return userRoles.stream().anyMatch(userRole ->
+ StringUtils.equals(userRole.getSubscriberId(), permissionProperties.getSubscriberId())
+ && StringUtils.equals(userRole.getServiceType(), permissionProperties.getServiceType())
+ );
+ }
+
@Override
- public boolean isTenantPermitted(String globalCustomerId, String serviceType, String tenantName) {
+ public boolean isTenantPermitted(String subscriberId, String serviceType, String tenantName) {
for (Role role : userRoles) {
- if (role.getSubscribeName().equals(globalCustomerId)
+ if (role.getSubscriberId().equals(subscriberId)
&& role.getServiceType().equals(serviceType)
&& (role.getTenant() == null || role.getTenant().equalsIgnoreCase(tenantName))) {
return true;
@@ -64,17 +70,4 @@ public class RoleValidatorByRoles implements RoleValidator {
return false;
}
- boolean isMsoRequestValid(RequestDetails msoRequest) {
- try {
- String globalSubscriberIdRequested = (String) ((Map) ((Map) msoRequest.getAdditionalProperties()
- .get("requestDetails")).get("subscriberInfo")).get("globalSubscriberId");
- String serviceType = (String) ((Map) ((Map) msoRequest.getAdditionalProperties().get("requestDetails"))
- .get("requestParameters")).get("subscriptionServiceType");
- return isServicePermitted(globalSubscriberIdRequested, serviceType);
- } catch (Exception e) {
- //Until we'll get the exact information regarding the tenants and the global customer id, we'll return true on unknown requests to mso
- return true;
- }
- }
-
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorFactory.java b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorFactory.java
new file mode 100644
index 000000000..b171ad7e7
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorFactory.java
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.portalsdk.core.util.SystemProperties;
+import org.onap.vid.properties.Features;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.togglz.core.manager.FeatureManager;
+
+@Component
+public class RoleValidatorFactory {
+ private final FeatureManager featureManager;
+
+ @Autowired
+ public RoleValidatorFactory(FeatureManager featureManager) {
+ this.featureManager = featureManager;
+ }
+
+
+ public RoleValidator by(List<Role> roles) {
+ final boolean disableRoles = StringUtils
+ .equals(SystemProperties.getProperty("role_management_activated"), "false");
+ return by(roles, disableRoles);
+ }
+
+ public RoleValidator by(List<Role> roles, boolean disableRoles) {
+
+ if(disableRoles) {
+ return new AlwaysValidRoleValidator();
+ }
+ else if (featureManager.isActive(Features.FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY)){
+ return new RoleValidatorsComposer(
+ new RoleValidatorBySubscriberAndServiceType(roles),
+ new RoleValidatorByOwningEntity(roles)
+ );
+ }
+ else {
+ return new RoleValidatorBySubscriberAndServiceType(roles);
+ }
+ }
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorsComposer.kt b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorsComposer.kt
new file mode 100644
index 000000000..d012cb3f3
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidatorsComposer.kt
@@ -0,0 +1,16 @@
+package org.onap.vid.roles
+
+class RoleValidatorsComposer(private vararg val roleValidators: RoleValidator) : RoleValidator {
+
+ constructor(roleValidators: Collection<RoleValidator>) : this(*roleValidators.toTypedArray())
+
+ override fun isServicePermitted(p: WithPermissionProperties): Boolean =
+ roleValidators.any { it.isServicePermitted(p) }
+
+ override fun isSubscriberPermitted(subscriberId: String?): Boolean =
+ roleValidators.any { it.isSubscriberPermitted(subscriberId) }
+
+ override fun isTenantPermitted(subscriberId: String?, serviceType: String?, tenantName: String?): Boolean =
+ roleValidators.any { it.isTenantPermitted(subscriberId, serviceType, tenantName) }
+
+}
diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java
index b3ac16884..1e79ab4c8 100644
--- a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java
+++ b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java
@@ -21,6 +21,8 @@
package org.onap.vid.services;
+import static java.util.Collections.emptyList;
+import static org.apache.commons.collections4.ListUtils.emptyIfNull;
import static org.onap.vid.aai.AaiClient.QUERY_FORMAT_RESOURCE;
import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
@@ -33,8 +35,10 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.validation.constraints.NotNull;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
@@ -85,6 +89,7 @@ import org.onap.vid.model.aaiTree.NodeType;
import org.onap.vid.model.aaiTree.RelatedVnf;
import org.onap.vid.model.aaiTree.VpnBinding;
import org.onap.vid.model.aaiTree.VpnBindingKt;
+import org.onap.vid.roles.PermissionPropertiesSubscriberAndServiceType;
import org.onap.vid.roles.RoleValidator;
import org.onap.vid.utils.Intersection;
import org.onap.vid.utils.Logging;
@@ -97,6 +102,7 @@ public class AaiServiceImpl implements AaiService {
private static final String SERVICE_INSTANCE_ID = "service-instance.service-instance-id";
private static final String SERVICE_TYPE = "service-subscription.service-type";
private static final String CUSTOMER_ID = "customer.global-customer-id";
+ private static final String OWNING_ENTITY_ID = "owning-entity.owning-entity-id";
private static final String SERVICE_INSTANCE_NAME = "service-instance.service-instance-name";
private static final String TENANT_NODE_TYPE = "tenant";
private static final String CLOUD_REGION_NODE_TYPE = "cloud-region";
@@ -167,39 +173,42 @@ public class AaiServiceImpl implements AaiService {
}
}
- private List<ServiceInstanceSearchResult> getServicesByOwningEntityId(List<String> owningEntities, RoleValidator roleValidator) {
+ List<ServiceInstanceSearchResult> getServicesByOwningEntityId(List<String> owningEntities, RoleValidator roleValidator) {
AaiResponse<OwningEntityResponse> owningEntityResponse = aaiClient.getServicesByOwningEntityId(owningEntities);
List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
if (owningEntityResponse.getT() != null) {
for (OwningEntity owningEntity : owningEntityResponse.getT().getOwningEntity()) {
if (owningEntity.getRelationshipList() != null) {
- serviceInstanceSearchResultList = convertRelationshipToSearchResult(owningEntity, serviceInstanceSearchResultList, roleValidator);
+ serviceInstanceSearchResultList.addAll(convertRelationshipToSearchResult(owningEntity, roleValidator, owningEntity.getOwningEntityId()));
}
}
}
return serviceInstanceSearchResultList;
}
- private List<ServiceInstanceSearchResult> getServicesByProjectNames(List<String> projectNames, RoleValidator roleValidator) {
+ List<ServiceInstanceSearchResult> getServicesByProjectNames(List<String> projectNames, RoleValidator roleValidator) {
AaiResponse<ProjectResponse> projectByIdResponse = aaiClient.getServicesByProjectNames(projectNames);
List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
if (projectByIdResponse.getT() != null) {
for (Project project : projectByIdResponse.getT().getProject()) {
if (project.getRelationshipList() != null) {
- serviceInstanceSearchResultList = convertRelationshipToSearchResult(project, serviceInstanceSearchResultList, roleValidator);
+ serviceInstanceSearchResultList.addAll(convertRelationshipToSearchResult(project, roleValidator, null));
}
}
}
return serviceInstanceSearchResultList;
}
- private List<ServiceInstanceSearchResult> convertRelationshipToSearchResult(AaiRelationResponse owningEntityResponse, List<ServiceInstanceSearchResult> serviceInstanceSearchResultList, RoleValidator roleValidator) {
- if (owningEntityResponse.getRelationshipList().getRelationship() != null) {
- List<Relationship> relationshipList = owningEntityResponse.getRelationshipList().getRelationship();
+ private List<ServiceInstanceSearchResult> convertRelationshipToSearchResult(AaiRelationResponse aaiRelationResponse, RoleValidator roleValidator, String owningEntityId) {
+ List<ServiceInstanceSearchResult> serviceInstanceSearchResultList = new ArrayList<>();
+ if (aaiRelationResponse.getRelationshipList().getRelationship() != null) {
+ List<Relationship> relationshipList = aaiRelationResponse.getRelationshipList().getRelationship();
for (Relationship relationship : relationshipList) {
ServiceInstanceSearchResult serviceInstanceSearchResult = new ServiceInstanceSearchResult();
extractRelationshipData(relationship, serviceInstanceSearchResult, roleValidator);
extractRelatedToProperty(relationship, serviceInstanceSearchResult);
+ serviceInstanceSearchResult.setOwningEntityId(owningEntityId);
+ serviceInstanceSearchResult.setIsPermitted(roleValidator.isServicePermitted(serviceInstanceSearchResult));
serviceInstanceSearchResultList.add(serviceInstanceSearchResult);
}
}
@@ -217,12 +226,9 @@ public class AaiServiceImpl implements AaiService {
} else if (key.equals(SERVICE_TYPE)) {
serviceInstanceSearchResult.setServiceType(relationshipData.getRelationshipValue());
} else if (key.equals(CUSTOMER_ID)) {
- serviceInstanceSearchResult.setGlobalCustomerId(relationshipData.getRelationshipValue());
+ serviceInstanceSearchResult.setSubscriberId(relationshipData.getRelationshipValue());
}
}
-
- boolean isPermitted = roleValidator.isServicePermitted(serviceInstanceSearchResult.getSubscriberName(), serviceInstanceSearchResult.getServiceType());
- serviceInstanceSearchResult.setIsPermitted(isPermitted);
}
}
@@ -265,10 +271,9 @@ public class AaiServiceImpl implements AaiService {
@Override
public AaiResponse getSubscriberData(String subscriberId, RoleValidator roleValidator, boolean omitServiceInstances) {
AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId, omitServiceInstances);
- String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
for (ServiceSubscription serviceSubscription : subscriberResponse.getT().serviceSubscriptions.serviceSubscription) {
- String serviceType = serviceSubscription.serviceType;
- serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
+ serviceSubscription.isPermitted = roleValidator.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(serviceSubscription, subscriberResponse.getT().globalCustomerId));
}
return subscriberResponse;
@@ -298,38 +303,45 @@ public class AaiServiceImpl implements AaiService {
private List<ServiceInstanceSearchResult> getServicesBySubscriber(String subscriberId, String instanceIdentifier, RoleValidator roleValidator) {
AaiResponse<Services> subscriberResponse = aaiClient.getSubscriberData(subscriberId, false);
- String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
String subscriberName = subscriberResponse.getT().subscriberName;
ServiceSubscriptions serviceSubscriptions = subscriberResponse.getT().serviceSubscriptions;
- return getSearchResultsForSubscriptions(serviceSubscriptions, subscriberId, instanceIdentifier, roleValidator, subscriberGlobalId, subscriberName);
-
+ return getSearchResultsForSubscriptions(serviceSubscriptions, subscriberId, instanceIdentifier, roleValidator, subscriberName);
}
- private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSubscriptions(ServiceSubscriptions serviceSubscriptions, String subscriberId, String instanceIdentifier, RoleValidator roleValidator, String subscriberGlobalId, String subscriberName) {
+ private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSubscriptions(
+ ServiceSubscriptions serviceSubscriptions, String subscriberId, String instanceIdentifier,
+ RoleValidator roleValidator, String subscriberName) {
ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
if (serviceSubscriptions != null) {
for (ServiceSubscription serviceSubscription : serviceSubscriptions.serviceSubscription) {
- String serviceType = serviceSubscription.serviceType;
- serviceSubscription.isPermitted = roleValidator.isServicePermitted(subscriberGlobalId, serviceType);
- ArrayList<ServiceInstanceSearchResult> resultsForSubscription = getSearchResultsForSingleSubscription(serviceSubscription, subscriberId, instanceIdentifier, subscriberName, serviceType);
- results.addAll(resultsForSubscription);
+ serviceSubscription.isPermitted = roleValidator.isServicePermitted(new PermissionPropertiesSubscriberAndServiceType(serviceSubscription, subscriberId));
+ results.addAll(getSearchResultsForSingleSubscription(
+ serviceSubscription, subscriberId, instanceIdentifier, subscriberName,
+ serviceSubscription.serviceType, roleValidator)
+ );
}
}
return results;
}
- private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSingleSubscription(ServiceSubscription serviceSubscription, String subscriberId, String instanceIdentifier, String subscriberName, String serviceType) {
+ private ArrayList<ServiceInstanceSearchResult> getSearchResultsForSingleSubscription(
+ ServiceSubscription serviceSubscription, String subscriberId, String instanceIdentifier, String subscriberName,
+ String serviceType, RoleValidator roleValidator) {
ArrayList<ServiceInstanceSearchResult> results = new ArrayList<>();
if (serviceSubscription.serviceInstances != null) {
for (ServiceInstance serviceInstance : serviceSubscription.serviceInstances.serviceInstance) {
+
ServiceInstanceSearchResult serviceInstanceSearchResult =
- new ServiceInstanceSearchResult(serviceInstance.serviceInstanceId, subscriberId, serviceType, serviceInstance.serviceInstanceName,
- subscriberName, serviceInstance.modelInvariantId, serviceInstance.modelVersionId, serviceSubscription.isPermitted);
+ new ServiceInstanceSearchResult(serviceInstance.serviceInstanceId, subscriberId, serviceType,
+ serviceInstance.serviceInstanceName, subscriberName, serviceInstance.modelInvariantId,
+ serviceInstance.modelVersionId, relatedOwningEntityId(serviceInstance), false);
+
+ serviceInstanceSearchResult.setIsPermitted(roleValidator.isServicePermitted(serviceInstanceSearchResult));
if ((instanceIdentifier == null) || (serviceInstanceMatchesIdentifier(instanceIdentifier, serviceInstance))){
results.add(serviceInstanceSearchResult);
@@ -340,6 +352,43 @@ public class AaiServiceImpl implements AaiService {
return results;
}
+ protected String relatedOwningEntityId(ServiceInstance serviceInstance) {
+ /*
+ For reference, consider the service-instance structure below. Method will null-safely extract the
+ `relationship-value` where `relationship-key` == `owning-entity.owning-entity-id`.
+
+ {
+ "service-instance-id": "5d521981-33be-4bb5-bb20-5616a9c52a5a",
+ ...
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "owning-entity",
+ "related-link": "/aai/v11/business/owning-entities/owning-entity/4d4ecf59-41f1-40d4-818d-885234680a42",
+ "relationship-data": [
+ {
+ "relationship-key": "owning-entity.owning-entity-id",
+ "relationship-value": "4d4ecf59-41f1-40d4-818d-885234680a42"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ */
+
+ Stream<RelationshipData> allRelationships =
+ Optional.ofNullable(serviceInstance.relationshipList)
+ .map(it -> it.getRelationship())
+ .map(it -> it.stream().flatMap(r -> emptyIfNull(r.getRelationDataList()).stream()))
+ .orElse(Stream.empty());
+
+ return allRelationships
+ .filter(r -> StringUtils.equals(r.getRelationshipKey(), OWNING_ENTITY_ID))
+ .map(it -> it.getRelationshipValue())
+ .findAny().orElse(null);
+ }
+
private boolean serviceInstanceMatchesIdentifier(String instanceIdentifier, ServiceInstance serviceInstance) {
return instanceIdentifier.equals(serviceInstance.serviceInstanceId) || instanceIdentifier.equals(serviceInstance.serviceInstanceName);
}
@@ -667,7 +716,7 @@ public class AaiServiceImpl implements AaiService {
return aaiTree.stream().map(VpnBindingKt::from).collect(Collectors.toList());
} catch (ExceptionWithRequestInfo exception) {
if (Objects.equals(404, exception.getHttpCode())) {
- return Collections.emptyList();
+ return emptyList();
}
throw exception;
}
@@ -683,7 +732,7 @@ public class AaiServiceImpl implements AaiService {
return aaiTree.stream().map(Network::from).collect(Collectors.toList());
} catch (ExceptionWithRequestInfo exception) {
if (Objects.equals(404, exception.getHttpCode())) {
- return Collections.emptyList();
+ return emptyList();
}
throw exception;
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogicImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogicImpl.java
index 2cc76492f..07c2d1593 100644
--- a/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogicImpl.java
+++ b/vid-app-common/src/main/java/org/onap/vid/services/AsyncInstantiationBusinessLogicImpl.java
@@ -170,7 +170,9 @@ public class AsyncInstantiationBusinessLogicImpl implements
int bulkSize = request.getBulkSize();
UUID templateId = UUID.randomUUID();
for (int i = 0; i < bulkSize; i++) {
- ServiceInstantiation requestPerJob = prepareServiceToBeUnique(request);
+ ServiceInstantiation clonedServiceInstantiation = cloneServiceInstantiation(request);
+ ServiceInstantiation requestPerJob = prepareServiceToBeUnique(clonedServiceInstantiation);
+ requestPerJob = clearStatusFromRequest(requestPerJob);
ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
JobType jobType = getJobType(requestPerJob);
final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
@@ -561,20 +563,28 @@ public class AsyncInstantiationBusinessLogicImpl implements
@Override
public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
+ serviceInstantiation.setBulkSize(1);
+ return replaceAllTrackById(serviceInstantiation);
+ }
+ private<T extends BaseResource> T replaceAllTrackById(T resource) {
+ resource.setTrackById(UUID.randomUUID().toString());
+ resource.getChildren().forEach(this::replaceAllTrackById);
+ return resource;
+ }
+
+ private ServiceInstantiation cloneServiceInstantiation(ServiceInstantiation serviceInstantiation) {
try {
- ServiceInstantiation clonedServiceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
- JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
- clonedServiceInstantiation.setBulkSize(1);
- return replaceAllTrackById(clonedServiceInstantiation);
+ return JACKSON_OBJECT_MAPPER.readValue(
+ JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
} catch (IOException e) {
throw new GenericUncheckedException(e);
}
-
}
- private<T extends BaseResource> T replaceAllTrackById(T resource) {
- resource.setTrackById(UUID.randomUUID().toString());
- resource.getChildren().forEach(this::replaceAllTrackById);
+ <T extends BaseResource> T clearStatusFromRequest(T resource) {
+ resource.setIsFailed(false);
+ resource.setStatusMessage(null);
+ resource.getChildren().forEach(this::clearStatusFromRequest);
return resource;
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java b/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java
index aa0031104..17520eef4 100644
--- a/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java
+++ b/vid-app-common/src/main/java/org/onap/vid/services/InstantiationTemplatesService.java
@@ -22,28 +22,39 @@ package org.onap.vid.services;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.toList;
+import java.util.Collection;
import java.util.Map;
+import java.util.Set;
import java.util.UUID;
import javax.inject.Inject;
+import org.jetbrains.annotations.NotNull;
+import org.onap.vid.asdc.beans.Service;
import org.onap.vid.dal.AsyncInstantiationRepository;
import org.onap.vid.model.ModelUtil;
import org.onap.vid.model.serviceInstantiation.BaseResource;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiationTemplate;
+import org.onap.vid.properties.Features;
import org.springframework.stereotype.Component;
+import org.togglz.core.manager.FeatureManager;
@Component
public class InstantiationTemplatesService {
private final ModelUtil modelUtil;
private final AsyncInstantiationRepository asyncInstantiationRepository;
+ private FeatureManager featureManager;
+
@Inject
public InstantiationTemplatesService(ModelUtil modelUtil,
- AsyncInstantiationRepository asyncInstantiationRepository) {
+ AsyncInstantiationRepository asyncInstantiationRepository,
+ FeatureManager featureManager) {
this.modelUtil = modelUtil;
this.asyncInstantiationRepository = asyncInstantiationRepository;
+ this.featureManager = featureManager;
}
public ServiceInstantiationTemplate getJobRequestAsTemplate(UUID jobId) {
@@ -64,4 +75,25 @@ public class InstantiationTemplatesService {
);
}
+ public Collection<Service> setOnEachServiceIsTemplateExists(Collection<Service> services){
+ if (!featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)){
+ return unsetTemplateExistsToAllServices(services);
+
+ }
+
+ Set<String> serviceModelIdsFromDB = asyncInstantiationRepository.getAllTemplatesServiceModelIds();
+
+ return services.stream().map(it -> setTemplateExistForService(it, serviceModelIdsFromDB)).collect(toList());
+ }
+
+ @NotNull
+ protected Collection<Service> unsetTemplateExistsToAllServices(Collection<Service> services) {
+ services.forEach(it -> it.setIsInstantiationTemplateExists(false));
+ return services;
+ }
+
+ protected Service setTemplateExistForService(Service service, Set<String> serviceModelIdsFromDb) {
+ service.setIsInstantiationTemplateExists(serviceModelIdsFromDb.contains(service.getUuid()));
+ return service;
+ }
}
diff --git a/vid-app-common/src/main/java/org/onap/vid/services/UserParamsContainer.kt b/vid-app-common/src/main/java/org/onap/vid/services/UserParamsContainer.kt
new file mode 100644
index 000000000..17cf88e3f
--- /dev/null
+++ b/vid-app-common/src/main/java/org/onap/vid/services/UserParamsContainer.kt
@@ -0,0 +1,40 @@
+package org.onap.vid.services
+
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue
+import org.onap.vid.mso.model.UserParamTypes
+
+class UserParamsContainer(instanceParams: Map<String, String>?, supplementaryParams: List<UserParamNameAndValue>?) {
+
+ val params:Map<String, String>
+
+ init {
+ params = aggregateAllInstanceParams(instanceParams, supplementaryParams)
+ }
+
+ private fun aggregateAllInstanceParams(
+ instanceParams: Map<String, String>?,
+ supplementaryParams: List<UserParamNameAndValue>?)
+ : Map<String, String> {
+ val instanceParamsSafe: Map<String, String> = instanceParams ?: emptyMap()
+ val supplementaryParamsSafe: Map<String, String> =
+ supplementaryParams?.associate{ it.name to it.value } ?: emptyMap()
+
+ return instanceParamsSafe.plus(supplementaryParamsSafe)
+ }
+
+ fun toALaCarte(): List<UserParamTypes> = toUserParamNameAndValue()
+
+ fun toMacroPre1806() : List<UserParamTypes> = toUserParamNameAndValue()
+
+ fun toMacroPost1806() : List<Map<String, String>> = toListOfMap()
+
+ private fun toUserParamNameAndValue(): List<UserParamNameAndValue> {
+ return params.map{UserParamNameAndValue(it.key, it.value)}.toList()
+ }
+
+ private fun toListOfMap() : List<Map<String, String>> {
+ return listOf(params)
+ }
+}
+
+
diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/KotlinUtils.kt b/vid-app-common/src/main/java/org/onap/vid/utils/KotlinUtils.kt
index 81afe29e0..83077f28c 100644
--- a/vid-app-common/src/main/java/org/onap/vid/utils/KotlinUtils.kt
+++ b/vid-app-common/src/main/java/org/onap/vid/utils/KotlinUtils.kt
@@ -23,11 +23,15 @@ package org.onap.vid.utils
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import org.apache.commons.lang3.StringUtils.isEmpty
+import org.togglz.core.Feature
+import org.togglz.core.manager.FeatureManager
inline fun <reified E: Enum<E>> getEnumFromMapOfStrings(map: Map<String, Any>, key:String, defaultValue:E): E {
return java.lang.Enum.valueOf(E::class.java, (map.getOrDefault(key, defaultValue.name) as String))
}
+fun FeatureManager.isNotActive(feature: Feature) = this.isActive(feature).not()
+
@JvmField val JACKSON_OBJECT_MAPPER: ObjectMapper = jacksonObjectMapper()
class JoshworksJacksonObjectMapper: io.joshworks.restclient.http.mapper.ObjectMapper {
diff --git a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java
index 43f059d54..f9894d1aa 100644
--- a/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java
+++ b/vid-app-common/src/main/java/org/onap/vid/utils/Logging.java
@@ -20,6 +20,7 @@
package org.onap.vid.utils;
+import static java.util.Collections.emptyMap;
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
import static org.apache.commons.lang3.exception.ExceptionUtils.getRootCause;
import static org.apache.commons.lang3.exception.ExceptionUtils.getThrowableList;
@@ -220,7 +221,7 @@ public class Logging {
<T> T withMDCInternal(Map<String, String> copyOfParentMDC, UncheckedThrowingSupplier<T> supplier) {
try {
- MDC.setContextMap(copyOfParentMDC);
+ MDC.setContextMap(defaultIfNull(copyOfParentMDC, emptyMap()));
return supplier.get();
} finally {
MDC.clear();
diff --git a/vid-app-common/src/main/webapp/app/vid/external/angular-moment/moment.min.js b/vid-app-common/src/main/webapp/app/vid/external/angular-moment/moment.min.js
index 57427d24e..5787a4085 100644
--- a/vid-app-common/src/main/webapp/app/vid/external/angular-moment/moment.min.js
+++ b/vid-app-common/src/main/webapp/app/vid/external/angular-moment/moment.min.js
@@ -1 +1 @@
-!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function c(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function l(e){return void 0===e}function d(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function h(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function f(e,t){var n,s=[];for(n=0;n<e.length;++n)s.push(t(e[n],n));return s}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function _(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function y(e,t,n,s){return Ot(e,t,n,s,!0).utc()}function g(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function p(e){if(null==e._isValid){var t=g(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function v(e){var t=y(NaN);return null!=e?_(g(t),e):g(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var r=c.momentProperties=[];function w(e,t){var n,s,i;if(l(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),l(t._i)||(e._i=t._i),l(t._f)||(e._f=t._f),l(t._l)||(e._l=t._l),l(t._strict)||(e._strict=t._strict),l(t._tzm)||(e._tzm=t._tzm),l(t._isUTC)||(e._isUTC=t._isUTC),l(t._offset)||(e._offset=t._offset),l(t._pf)||(e._pf=g(t)),l(t._locale)||(e._locale=t._locale),0<r.length)for(n=0;n<r.length;n++)l(i=t[s=r[n]])||(e[s]=i);return e}var t=!1;function M(e){w(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,c.updateOffset(this),t=!1)}function S(e){return e instanceof M||null!=e&&null!=e._isAMomentObject}function D(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function k(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=D(t)),n}function a(e,t,n){var s,i=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),a=0;for(s=0;s<i;s++)(n&&e[s]!==t[s]||!n&&k(e[s])!==k(t[s]))&&a++;return a+r}function Y(e){!1===c.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return _(function(){if(null!=c.deprecationHandler&&c.deprecationHandler(null,i),a){for(var e,t=[],n=0;n<arguments.length;n++){if(e="","object"==typeof arguments[n]){for(var s in e+="\n["+n+"] ",arguments[0])e+=s+": "+arguments[0][s]+", ";e=e.slice(0,-2)}else e=arguments[n];t.push(e)}Y(i+"\nArguments: "+Array.prototype.slice.call(t).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,O={};function T(e,t){null!=c.deprecationHandler&&c.deprecationHandler(e,t),O[e]||(Y(t),O[e]=!0)}function x(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function b(e,t){var n,s=_({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},_(s[n],e[n]),_(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=_({},s[n]));return s}function P(e){null!=e&&this.set(e)}c.suppressDeprecationWarnings=!1,c.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};var W={};function H(e,t){var n=e.toLowerCase();W[n]=W[n+"s"]=W[t]=e}function R(e){return"string"==typeof e?W[e]||W[e.toLowerCase()]:void 0}function C(e){var t,n,s={};for(n in e)m(e,n)&&(t=R(n))&&(s[t]=e[n]);return s}var F={};function L(e,t){F[e]=t}function U(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,G=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},E={};function I(e,t,n,s){var i=s;"string"==typeof s&&(i=function(){return this[s]()}),e&&(E[e]=i),t&&(E[t[0]]=function(){return U(i.apply(this,arguments),t[1],t[2])}),n&&(E[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=j(t,e.localeData()),V[t]=V[t]||function(s){var e,i,t,r=s.match(N);for(e=0,i=r.length;e<i;e++)E[r[e]]?r[e]=E[r[e]]:r[e]=(t=r[e]).match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"");return function(e){var t,n="";for(t=0;t<i;t++)n+=x(r[t])?r[t].call(e,s):r[t];return n}}(t),V[t](e)):e.localeData().invalidDate()}function j(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(G.lastIndex=0;0<=n&&G.test(e);)e=e.replace(G,s),G.lastIndex=0,n-=1;return e}var Z=/\d/,z=/\d\d/,$=/\d{3}/,q=/\d{4}/,J=/[+-]?\d{6}/,B=/\d\d?/,Q=/\d\d\d\d?/,X=/\d\d\d\d\d\d?/,K=/\d{1,3}/,ee=/\d{1,4}/,te=/[+-]?\d{1,6}/,ne=/\d+/,se=/[+-]?\d+/,ie=/Z|[+-]\d\d:?\d\d/gi,re=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,oe={};function ue(e,n,s){oe[e]=x(n)?n:function(e,t){return e&&s?s:n}}function le(e,t){return m(oe,e)?oe[e](t._strict,t._locale):new RegExp(de(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function de(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var he={};function ce(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),d(n)&&(s=function(e,t){t[n]=k(e)}),t=0;t<e.length;t++)he[e[t]]=s}function fe(e,i){ce(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var me=0,_e=1,ye=2,ge=3,pe=4,ve=5,we=6,Me=7,Se=8;function De(e){return ke(e)?366:365}function ke(e){return e%4==0&&e%100!=0||e%400==0}I("Y",0,0,function(){var e=this.year();return e<=9999?""+e:"+"+e}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),H("year","y"),L("year",1),ue("Y",se),ue("YY",B,z),ue("YYYY",ee,q),ue("YYYYY",te,J),ue("YYYYYY",te,J),ce(["YYYYY","YYYYYY"],me),ce("YYYY",function(e,t){t[me]=2===e.length?c.parseTwoDigitYear(e):k(e)}),ce("YY",function(e,t){t[me]=c.parseTwoDigitYear(e)}),ce("Y",function(e,t){t[me]=parseInt(e,10)}),c.parseTwoDigitYear=function(e){return k(e)+(68<k(e)?1900:2e3)};var Ye,Oe=Te("FullYear",!0);function Te(t,n){return function(e){return null!=e?(be(this,t,e),c.updateOffset(this,n),this):xe(this,t)}}function xe(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function be(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&ke(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Pe(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function Pe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1===s?ke(e)?29:28:31-s%7%2}Ye=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t<this.length;++t)if(this[t]===e)return t;return-1},I("M",["MM",2],"Mo",function(){return this.month()+1}),I("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),I("MMMM",0,0,function(e){return this.localeData().months(this,e)}),H("month","M"),L("month",8),ue("M",B),ue("MM",B,z),ue("MMM",function(e,t){return t.monthsShortRegex(e)}),ue("MMMM",function(e,t){return t.monthsRegex(e)}),ce(["M","MM"],function(e,t){t[_e]=k(e)-1}),ce(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[_e]=i:g(n).invalidMonth=e});var We=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,He="January_February_March_April_May_June_July_August_September_October_November_December".split("_");var Re="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function Ce(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=k(t);else if(!d(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),Pe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Fe(e){return null!=e?(Ce(this,e),c.updateOffset(this,!0),this):xe(this,"Month")}var Le=ae;var Ue=ae;function Ne(){function e(e,t){return t.length-e.length}var t,n,s=[],i=[],r=[];for(t=0;t<12;t++)n=y([2e3,t]),s.push(this.monthsShort(n,"")),i.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(s.sort(e),i.sort(e),r.sort(e),t=0;t<12;t++)s[t]=de(s[t]),i[t]=de(i[t]);for(t=0;t<24;t++)r[t]=de(r[t]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+s.join("|")+")","i")}function Ge(e){var t=new Date(Date.UTC.apply(null,arguments));return e<100&&0<=e&&isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e),t}function Ve(e,t,n){var s=7+t-n;return-((7+Ge(e,0,s).getUTCDay()-t)%7)+s-1}function Ee(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+Ve(e,s,i);return o<=0?a=De(r=e-1)+o:o>De(e)?(r=e+1,a=o-De(e)):(r=e,a=o),{year:r,dayOfYear:a}}function Ie(e,t,n){var s,i,r=Ve(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ae(i=e.year()-1,t,n):a>Ae(e.year(),t,n)?(s=a-Ae(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ae(e,t,n){var s=Ve(e,t,n),i=Ve(e+1,t,n);return(De(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),H("week","w"),H("isoWeek","W"),L("week",5),L("isoWeek",5),ue("w",B),ue("ww",B,z),ue("W",B),ue("WW",B,z),fe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=k(e)});I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),H("day","d"),H("weekday","e"),H("isoWeekday","E"),L("day",11),L("weekday",11),L("isoWeekday",11),ue("d",B),ue("e",B),ue("E",B),ue("dd",function(e,t){return t.weekdaysMinRegex(e)}),ue("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ue("dddd",function(e,t){return t.weekdaysRegex(e)}),fe(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:g(n).invalidWeekday=e}),fe(["d","e","E"],function(e,t,n,s){t[s]=k(e)});var je="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var Ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var ze="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var $e=ae;var qe=ae;var Je=ae;function Be(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=y([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=de(o[t]),u[t]=de(u[t]),l[t]=de(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Qe(){return this.hours()%12||12}function Xe(e,t){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function Ke(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,Qe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)}),I("hmmss",0,0,function(){return""+Qe.apply(this)+U(this.minutes(),2)+U(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+U(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+U(this.minutes(),2)+U(this.seconds(),2)}),Xe("a",!0),Xe("A",!1),H("hour","h"),L("hour",13),ue("a",Ke),ue("A",Ke),ue("H",B),ue("h",B),ue("k",B),ue("HH",B,z),ue("hh",B,z),ue("kk",B,z),ue("hmm",Q),ue("hmmss",X),ue("Hmm",Q),ue("Hmmss",X),ce(["H","HH"],ge),ce(["k","kk"],function(e,t,n){var s=k(e);t[ge]=24===s?0:s}),ce(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ce(["h","hh"],function(e,t,n){t[ge]=k(e),g(n).bigHour=!0}),ce("hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s)),g(n).bigHour=!0}),ce("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i)),g(n).bigHour=!0}),ce("Hmm",function(e,t,n){var s=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s))}),ce("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=k(e.substr(0,s)),t[pe]=k(e.substr(s,2)),t[ve]=k(e.substr(i))});var et,tt=Te("Hours",!0),nt={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{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"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,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"},months:He,monthsShort:Re,week:{dow:0,doy:6},weekdays:je,weekdaysMin:ze,weekdaysShort:Ze,meridiemParse:/[ap]\.?m?\.?/i},st={},it={};function rt(e){return e?e.toLowerCase().replace("_","-"):e}function at(e){var t=null;if(!st[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=et._abbr,require("./locale/"+e),ot(t)}catch(e){}return st[e]}function ot(e,t){var n;return e&&((n=l(t)?lt(e):ut(e,t))?et=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),et._abbr}function ut(e,t){if(null!==t){var n,s=nt;if(t.abbr=e,null!=st[e])T("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."),s=st[e]._config;else if(null!=t.parentLocale)if(null!=st[t.parentLocale])s=st[t.parentLocale]._config;else{if(null==(n=at(t.parentLocale)))return it[t.parentLocale]||(it[t.parentLocale]=[]),it[t.parentLocale].push({name:e,config:t}),null;s=n._config}return st[e]=new P(b(s,t)),it[e]&&it[e].forEach(function(e){ut(e.name,e.config)}),ot(e),st[e]}return delete st[e],null}function lt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return et;if(!o(e)){if(t=at(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=rt(e[r]).split("-")).length,n=(n=rt(e[r+1]))?n.split("-"):null;0<t;){if(s=at(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&a(i,n,!0)>=t-1)break;t--}r++}return et}(e)}function dt(e){var t,n=e._a;return n&&-2===g(e).overflow&&(t=n[_e]<0||11<n[_e]?_e:n[ye]<1||n[ye]>Pe(n[me],n[_e])?ye:n[ge]<0||24<n[ge]||24===n[ge]&&(0!==n[pe]||0!==n[ve]||0!==n[we])?ge:n[pe]<0||59<n[pe]?pe:n[ve]<0||59<n[ve]?ve:n[we]<0||999<n[we]?we:-1,g(e)._overflowDayOfYear&&(t<me||ye<t)&&(t=ye),g(e)._overflowWeeks&&-1===t&&(t=Me),g(e)._overflowWeekday&&-1===t&&(t=Se),g(e).overflow=t),e}function ht(e,t,n){return null!=e?e:null!=t?t:n}function ct(e){var t,n,s,i,r,a=[];if(!e._d){var o,u;for(o=e,u=new Date(c.now()),s=o._useUTC?[u.getUTCFullYear(),u.getUTCMonth(),u.getUTCDate()]:[u.getFullYear(),u.getMonth(),u.getDate()],e._w&&null==e._a[ye]&&null==e._a[_e]&&function(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ht(t.GG,e._a[me],Ie(Tt(),1,4).year),s=ht(t.W,1),((i=ht(t.E,1))<1||7<i)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ie(Tt(),r,a);n=ht(t.gg,e._a[me],l.year),s=ht(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r}s<1||s>Ae(n,r,a)?g(e)._overflowWeeks=!0:null!=u?g(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[me]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=ht(e._a[me],s[me]),(e._dayOfYear>De(r)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),n=Ge(r,0,e._dayOfYear),e._a[_e]=n.getUTCMonth(),e._a[ye]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=s[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[pe]&&0===e._a[ve]&&0===e._a[we]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Ge:function(e,t,n,s,i,r,a){var o=new Date(e,t,n,s,i,r,a);return e<100&&0<=e&&isFinite(o.getFullYear())&&o.setFullYear(e),o}).apply(null,a),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(g(e).weekdayMismatch=!0)}}var ft=/^\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)?)?$/,mt=/^\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)?)?$/,_t=/Z|[+-]\d\d(?::?\d\d)?/,yt=[["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/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],gt=[["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/]],pt=/^\/?Date\((\-?\d+)/i;function vt(e){var t,n,s,i,r,a,o=e._i,u=ft.exec(o)||mt.exec(o);if(u){for(g(e).iso=!0,t=0,n=yt.length;t<n;t++)if(yt[t][1].exec(u[1])){i=yt[t][0],s=!1!==yt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[3])){r=(u[2]||" ")+gt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!_t.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),kt(e)}else e._isValid=!1}var wt=/^(?:(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}))$/;function Mt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),Re.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}var St={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Dt(e){var t,n,s,i=wt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim());if(i){var r=Mt(i[4],i[3],i[2],i[5],i[6],i[7]);if(t=i[1],n=r,s=e,t&&Ze.indexOf(t)!==new Date(n[0],n[1],n[2]).getDay()&&(g(s).weekdayMismatch=!0,!(s._isValid=!1)))return;e._a=r,e._tzm=function(e,t,n){if(e)return St[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return(s-i)/100*60+i}(i[8],i[9],i[10]),e._d=Ge.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),g(e).rfc2822=!0}else e._isValid=!1}function kt(e){if(e._f!==c.ISO_8601)if(e._f!==c.RFC_2822){e._a=[],g(e).empty=!0;var t,n,s,i,r,a,o,u,l=""+e._i,d=l.length,h=0;for(s=j(e._f,e._locale).match(N)||[],t=0;t<s.length;t++)i=s[t],(n=(l.match(le(i,e))||[])[0])&&(0<(r=l.substr(0,l.indexOf(n))).length&&g(e).unusedInput.push(r),l=l.slice(l.indexOf(n)+n.length),h+=n.length),E[i]?(n?g(e).empty=!1:g(e).unusedTokens.push(i),a=i,u=e,null!=(o=n)&&m(he,a)&&he[a](o,u._a,u,a)):e._strict&&!n&&g(e).unusedTokens.push(i);g(e).charsLeftOver=d-h,0<l.length&&g(e).unusedInput.push(l),e._a[ge]<=12&&!0===g(e).bigHour&&0<e._a[ge]&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[ge]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[ge],e._meridiem),ct(e),dt(e)}else Dt(e);else vt(e)}function Yt(e){var t,n,s,i,r=e._i,a=e._f;return e._locale=e._locale||lt(e._l),null===r||void 0===a&&""===r?v({nullInput:!0}):("string"==typeof r&&(e._i=r=e._locale.preparse(r)),S(r)?new M(dt(r)):(h(r)?e._d=r:o(a)?function(e){var t,n,s,i,r;if(0===e._f.length)return g(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,t=w({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],kt(t),p(t)&&(r+=g(t).charsLeftOver,r+=10*g(t).unusedTokens.length,g(t).score=r,(null==s||r<s)&&(s=r,n=t));_(e,n||t)}(e):a?kt(e):l(n=(t=e)._i)?t._d=new Date(c.now()):h(n)?t._d=new Date(n.valueOf()):"string"==typeof n?(s=t,null===(i=pt.exec(s._i))?(vt(s),!1===s._isValid&&(delete s._isValid,Dt(s),!1===s._isValid&&(delete s._isValid,c.createFromInputFallback(s)))):s._d=new Date(+i[1])):o(n)?(t._a=f(n.slice(0),function(e){return parseInt(e,10)}),ct(t)):u(n)?function(e){if(!e._d){var t=C(e._i);e._a=f([t.year,t.month,t.day||t.date,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),ct(e)}}(t):d(n)?t._d=new Date(n):c.createFromInputFallback(t),p(e)||(e._d=null),e))}function Ot(e,t,n,s,i){var r,a={};return!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&function(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(e.hasOwnProperty(t))return!1;return!0}(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new M(dt(Yt(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function Tt(e,t,n,s){return Ot(e,t,n,s,!1)}c.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),c.ISO_8601=function(){},c.RFC_2822=function(){};var xt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:v()}),bt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:v()});function Pt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return Tt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Wt=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ht(e){var t=C(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,d=t.millisecond||0;this._isValid=function(e){for(var t in e)if(-1===Ye.call(Wt,t)||null!=e[t]&&isNaN(e[t]))return!1;for(var n=!1,s=0;s<Wt.length;++s)if(e[Wt[s]]){if(n)return!1;parseFloat(e[Wt[s]])!==k(e[Wt[s]])&&(n=!0)}return!0}(t),this._milliseconds=+d+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=lt(),this._bubble()}function Rt(e){return e instanceof Ht}function Ct(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){I(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+U(~~(e/60),2)+n+U(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ue("Z",re),ue("ZZ",re),ce(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Ut(re,e)});var Lt=/([\+\-]|\d\d)/gi;function Ut(e,t){var n=(t||"").match(e);if(null===n)return null;var s=((n[n.length-1]||[])+"").match(Lt)||["-",0,0],i=60*s[1]+k(s[2]);return 0===i?0:"+"===s[0]?i:-i}function Nt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(S(e)||h(e)?e.valueOf():Tt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),c.updateOffset(n,!1),n):Tt(e).local()}function Gt(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Vt(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}c.updateOffset=function(){};var Et=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,It=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function At(e,t){var n,s,i,r=e,a=null;return Rt(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:d(e)?(r={},t?r[t]=e:r.milliseconds=e):(a=Et.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:k(a[ye])*n,h:k(a[ge])*n,m:k(a[pe])*n,s:k(a[ve])*n,ms:k(Ct(1e3*a[we]))*n}):(a=It.exec(e))?(n="-"===a[1]?-1:(a[1],1),r={y:jt(a[2],n),M:jt(a[3],n),w:jt(a[4],n),d:jt(a[5],n),h:jt(a[6],n),m:jt(a[7],n),s:jt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Nt(t,e),e.isBefore(t)?n=Zt(e,t):((n=Zt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(Tt(r.from),Tt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ht(r),Rt(e)&&m(e,"_locale")&&(s._locale=e._locale),s}function jt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function Zt(e,t){var n={milliseconds:0,months:0};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function zt(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(T(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),$t(this,At(e="string"==typeof e?+e:e,t),s),this}}function $t(e,t,n,s){var i=t._milliseconds,r=Ct(t._days),a=Ct(t._months);e.isValid()&&(s=null==s||s,a&&Ce(e,xe(e,"Month")+a*n),r&&be(e,"Date",xe(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&c.updateOffset(e,r||a))}At.fn=Ht.prototype,At.invalid=function(){return At(NaN)};var qt=zt(1,"add"),Jt=zt(-1,"subtract");function Bt(e,t){var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months");return-(n+(t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(n+1,"months")-s)))||0}function Qt(e){var t;return void 0===e?this._locale._abbr:(null!=(t=lt(e))&&(this._locale=t),this)}c.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",c.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Xt=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function Kt(){return this._locale}function en(e,t){I(0,[e,e.length],0,t)}function tn(e,t,n,s,i){var r;return null==e?Ie(this,s,i).year:((r=Ae(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ge(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),en("gggg","weekYear"),en("ggggg","weekYear"),en("GGGG","isoWeekYear"),en("GGGGG","isoWeekYear"),H("weekYear","gg"),H("isoWeekYear","GG"),L("weekYear",1),L("isoWeekYear",1),ue("G",se),ue("g",se),ue("GG",B,z),ue("gg",B,z),ue("GGGG",ee,q),ue("gggg",ee,q),ue("GGGGG",te,J),ue("ggggg",te,J),fe(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=k(e)}),fe(["gg","GG"],function(e,t,n,s){t[s]=c.parseTwoDigitYear(e)}),I("Q",0,"Qo","quarter"),H("quarter","Q"),L("quarter",7),ue("Q",Z),ce("Q",function(e,t){t[_e]=3*(k(e)-1)}),I("D",["DD",2],"Do","date"),H("date","D"),L("date",9),ue("D",B),ue("DD",B,z),ue("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ce(["D","DD"],ye),ce("Do",function(e,t){t[ye]=k(e.match(B)[0])});var nn=Te("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),H("dayOfYear","DDD"),L("dayOfYear",4),ue("DDD",K),ue("DDDD",$),ce(["DDD","DDDD"],function(e,t,n){n._dayOfYear=k(e)}),I("m",["mm",2],0,"minute"),H("minute","m"),L("minute",14),ue("m",B),ue("mm",B,z),ce(["m","mm"],pe);var sn=Te("Minutes",!1);I("s",["ss",2],0,"second"),H("second","s"),L("second",15),ue("s",B),ue("ss",B,z),ce(["s","ss"],ve);var rn,an=Te("Seconds",!1);for(I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),H("millisecond","ms"),L("millisecond",16),ue("S",K,Z),ue("SS",K,z),ue("SSS",K,$),rn="SSSS";rn.length<=9;rn+="S")ue(rn,ne);function on(e,t){t[we]=k(1e3*("0."+e))}for(rn="S";rn.length<=9;rn+="S")ce(rn,on);var un=Te("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var ln=M.prototype;function dn(e){return e}ln.add=qt,ln.calendar=function(e,t){var n=e||Tt(),s=Nt(n,this).startOf("day"),i=c.calendarFormat(this,s)||"sameElse",r=t&&(x(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,Tt(n)))},ln.clone=function(){return new M(this)},ln.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Nt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=R(t)){case"year":r=Bt(this,s)/12;break;case"month":r=Bt(this,s);break;case"quarter":r=Bt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:D(r)},ln.endOf=function(e){return void 0===(e=R(e))||"millisecond"===e?this:("date"===e&&(e="day"),this.startOf(e).add(1,"isoWeek"===e?"week":e).subtract(1,"ms"))},ln.format=function(e){e||(e=this.isUtc()?c.defaultFormatUtc:c.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},ln.from=function(e,t){return this.isValid()&&(S(e)&&e.isValid()||Tt(e).isValid())?At({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},ln.fromNow=function(e){return this.from(Tt(),e)},ln.to=function(e,t){return this.isValid()&&(S(e)&&e.isValid()||Tt(e).isValid())?At({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},ln.toNow=function(e){return this.to(Tt(),e)},ln.get=function(e){return x(this[e=R(e)])?this[e]():this},ln.invalidAt=function(){return g(this).overflow},ln.isAfter=function(e,t){var n=S(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(l(t)?"millisecond":t))?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},ln.isBefore=function(e,t){var n=S(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=R(l(t)?"millisecond":t))?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},ln.isBetween=function(e,t,n,s){return("("===(s=s||"()")[0]?this.isAfter(e,n):!this.isBefore(e,n))&&(")"===s[1]?this.isBefore(t,n):!this.isAfter(t,n))},ln.isSame=function(e,t){var n,s=S(e)?e:Tt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=R(t||"millisecond"))?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},ln.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},ln.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},ln.isValid=function(){return p(this)},ln.lang=Xt,ln.locale=Qt,ln.localeData=Kt,ln.max=bt,ln.min=xt,ln.parsingFlags=function(){return _({},g(this))},ln.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t=[];for(var n in e)t.push({unit:n,priority:F[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}(e=C(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(x(this[e=R(e)]))return this[e](t);return this},ln.startOf=function(e){switch(e=R(e)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===e&&this.weekday(0),"isoWeek"===e&&this.isoWeekday(1),"quarter"===e&&this.month(3*Math.floor(this.month()/3)),this},ln.subtract=Jt,ln.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},ln.toObject=function(){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()}},ln.toDate=function(){return new Date(this.valueOf())},ln.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):x(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},ln.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i=t+'[")]';return this.format(n+s+"-MM-DD[T]HH:mm:ss.SSS"+i)},ln.toJSON=function(){return this.isValid()?this.toISOString():null},ln.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},ln.unix=function(){return Math.floor(this.valueOf()/1e3)},ln.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},ln.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},ln.year=Oe,ln.isLeapYear=function(){return ke(this.year())},ln.weekYear=function(e){return tn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},ln.isoWeekYear=function(e){return tn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},ln.quarter=ln.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},ln.month=Fe,ln.daysInMonth=function(){return Pe(this.year(),this.month())},ln.week=ln.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},ln.isoWeek=ln.isoWeeks=function(e){var t=Ie(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},ln.weeksInYear=function(){var e=this.localeData()._week;return Ae(this.year(),e.dow,e.doy)},ln.isoWeeksInYear=function(){return Ae(this.year(),1,4)},ln.date=nn,ln.day=ln.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},ln.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},ln.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=(n=e,s=this.localeData(),"string"==typeof n?s.weekdaysParse(n)%7||7:isNaN(n)?null:n);return this.day(this.day()%7?t:t-7)}return this.day()||7;var n,s},ln.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},ln.hour=ln.hours=tt,ln.minute=ln.minutes=sn,ln.second=ln.seconds=an,ln.millisecond=ln.milliseconds=un,ln.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null!=e){if("string"==typeof e){if(null===(e=Ut(re,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Gt(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?$t(this,At(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,c.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?i:Gt(this)},ln.utc=function(e){return this.utcOffset(0,e)},ln.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Gt(this),"m")),this},ln.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Ut(ie,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},ln.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Tt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},ln.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},ln.isLocal=function(){return!!this.isValid()&&!this._isUTC},ln.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},ln.isUtc=Vt,ln.isUTC=Vt,ln.zoneAbbr=function(){return this._isUTC?"UTC":""},ln.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},ln.dates=n("dates accessor is deprecated. Use date instead.",nn),ln.months=n("months accessor is deprecated. Use month instead",Fe),ln.years=n("years accessor is deprecated. Use year instead",Oe),ln.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),ln.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var e={};if(w(e,this),(e=Yt(e))._a){var t=e._isUTC?y(e._a):Tt(e._a);this._isDSTShifted=this.isValid()&&0<a(e._a,t.toArray())}else this._isDSTShifted=!1;return this._isDSTShifted});var hn=P.prototype;function cn(e,t,n,s){var i=lt(),r=y().set(s,t);return i[n](r,e)}function fn(e,t,n){if(d(e)&&(t=e,e=void 0),e=e||"",null!=t)return cn(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=cn(e,s,n,"month");return i}function mn(e,t,n,s){"boolean"==typeof e?d(t)&&(n=t,t=void 0):(t=e,e=!1,d(n=t)&&(n=t,t=void 0)),t=t||"";var i,r=lt(),a=e?r._week.dow:0;if(null!=n)return cn(t,(n+a)%7,s,"day");var o=[];for(i=0;i<7;i++)o[i]=cn(t,(i+a)%7,s,"day");return o}hn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return x(s)?s.call(t,n):s},hn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},hn.invalidDate=function(){return this._invalidDate},hn.ordinal=function(e){return this._ordinal.replace("%d",e)},hn.preparse=dn,hn.postformat=dn,hn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return x(i)?i(e,t,n,s):i.replace(/%d/i,e)},hn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return x(n)?n(t):n.replace(/%s/i,t)},hn.set=function(e){var t,n;for(n in e)x(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},hn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||We).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},hn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[We.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},hn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=y([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=y([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},hn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=Ue),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},hn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Le),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},hn.week=function(e){return Ie(e,this._week.dow,this._week.doy).week},hn.firstDayOfYear=function(){return this._week.doy},hn.firstDayOfWeek=function(){return this._week.dow},hn.weekdays=function(e,t){return e?o(this._weekdays)?this._weekdays[e.day()]:this._weekdays[this._weekdays.isFormat.test(t)?"format":"standalone"][e.day()]:o(this._weekdays)?this._weekdays:this._weekdays.standalone},hn.weekdaysMin=function(e){return e?this._weekdaysMin[e.day()]:this._weekdaysMin},hn.weekdaysShort=function(e){return e?this._weekdaysShort[e.day()]:this._weekdaysShort},hn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=y([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=y([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".",".?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},hn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=$e),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},hn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=qe),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},hn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Be.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Je),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},hn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},hn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},ot("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===k(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),c.lang=n("moment.lang is deprecated. Use moment.locale instead.",ot),c.langData=n("moment.langData is deprecated. Use moment.localeData instead.",lt);var _n=Math.abs;function yn(e,t,n,s){var i=At(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function gn(e){return e<0?Math.floor(e):Math.ceil(e)}function pn(e){return 4800*e/146097}function vn(e){return 146097*e/4800}function wn(e){return function(){return this.as(e)}}var Mn=wn("ms"),Sn=wn("s"),Dn=wn("m"),kn=wn("h"),Yn=wn("d"),On=wn("w"),Tn=wn("M"),xn=wn("y");function bn(e){return function(){return this.isValid()?this._data[e]:NaN}}var Pn=bn("milliseconds"),Wn=bn("seconds"),Hn=bn("minutes"),Rn=bn("hours"),Cn=bn("days"),Fn=bn("months"),Ln=bn("years");var Un=Math.round,Nn={ss:44,s:45,m:45,h:22,d:26,M:11};var Gn=Math.abs;function Vn(e){return(0<e)-(e<0)||+e}function En(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=Gn(this._milliseconds)/1e3,s=Gn(this._days),i=Gn(this._months);t=D((e=D(n/60))/60),n%=60,e%=60;var r=D(i/12),a=i%=12,o=s,u=t,l=e,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=Vn(this._months)!==Vn(h)?"-":"",m=Vn(this._days)!==Vn(h)?"-":"",_=Vn(this._milliseconds)!==Vn(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||d?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(d?_+d+"S":"")}var In=Ht.prototype;return In.isValid=function(){return this._isValid},In.abs=function(){var e=this._data;return this._milliseconds=_n(this._milliseconds),this._days=_n(this._days),this._months=_n(this._months),e.milliseconds=_n(e.milliseconds),e.seconds=_n(e.seconds),e.minutes=_n(e.minutes),e.hours=_n(e.hours),e.months=_n(e.months),e.years=_n(e.years),this},In.add=function(e,t){return yn(this,e,t,1)},In.subtract=function(e,t){return yn(this,e,t,-1)},In.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=R(e))||"year"===e)return t=this._days+s/864e5,n=this._months+pn(t),"month"===e?n:n/12;switch(t=this._days+Math.round(vn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},In.asMilliseconds=Mn,In.asSeconds=Sn,In.asMinutes=Dn,In.asHours=kn,In.asDays=Yn,In.asWeeks=On,In.asMonths=Tn,In.asYears=xn,In.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12):NaN},In._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*gn(vn(o)+a),o=a=0),u.milliseconds=r%1e3,e=D(r/1e3),u.seconds=e%60,t=D(e/60),u.minutes=t%60,n=D(t/60),u.hours=n%24,o+=i=D(pn(a+=D(n/24))),a-=gn(vn(i)),s=D(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},In.clone=function(){return At(this)},In.get=function(e){return e=R(e),this.isValid()?this[e+"s"]():NaN},In.milliseconds=Pn,In.seconds=Wn,In.minutes=Hn,In.hours=Rn,In.days=Cn,In.weeks=function(){return D(this.days()/7)},In.months=Fn,In.years=Ln,In.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t,n,s,i,r,a,o,u,l,d,h,c=this.localeData(),f=(n=!e,s=c,i=At(t=this).abs(),r=Un(i.as("s")),a=Un(i.as("m")),o=Un(i.as("h")),u=Un(i.as("d")),l=Un(i.as("M")),d=Un(i.as("y")),(h=r<=Nn.ss&&["s",r]||r<Nn.s&&["ss",r]||a<=1&&["m"]||a<Nn.m&&["mm",a]||o<=1&&["h"]||o<Nn.h&&["hh",o]||u<=1&&["d"]||u<Nn.d&&["dd",u]||l<=1&&["M"]||l<Nn.M&&["MM",l]||d<=1&&["y"]||["yy",d])[2]=n,h[3]=0<+t,h[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,h));return e&&(f=c.pastFuture(+this,f)),c.postformat(f)},In.toISOString=En,In.toString=En,In.toJSON=En,In.locale=Qt,In.localeData=Kt,In.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",En),In.lang=Xt,I("X",0,0,"unix"),I("x",0,0,"valueOf"),ue("x",se),ue("X",/[+-]?\d+(\.\d{1,3})?/),ce("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),ce("x",function(e,t,n){n._d=new Date(k(e))}),c.version="2.22.1",e=Tt,c.fn=ln,c.min=function(){return Pt("isBefore",[].slice.call(arguments,0))},c.max=function(){return Pt("isAfter",[].slice.call(arguments,0))},c.now=function(){return Date.now?Date.now():+new Date},c.utc=y,c.unix=function(e){return Tt(1e3*e)},c.months=function(e,t){return fn(e,t,"months")},c.isDate=h,c.locale=ot,c.invalid=v,c.duration=At,c.isMoment=S,c.weekdays=function(e,t,n){return mn(e,t,n,"weekdays")},c.parseZone=function(){return Tt.apply(null,arguments).parseZone()},c.localeData=lt,c.isDuration=Rt,c.monthsShort=function(e,t){return fn(e,t,"monthsShort")},c.weekdaysMin=function(e,t,n){return mn(e,t,n,"weekdaysMin")},c.defineLocale=ut,c.updateLocale=function(e,t){if(null!=t){var n,s,i=nt;null!=(s=at(e))&&(i=s._config),(n=new P(t=b(i,t))).parentLocale=st[e],st[e]=n,ot(e)}else null!=st[e]&&(null!=st[e].parentLocale?st[e]=st[e].parentLocale:null!=st[e]&&delete st[e]);return st[e]},c.locales=function(){return s(st)},c.weekdaysShort=function(e,t,n){return mn(e,t,n,"weekdaysShort")},c.normalizeUnits=R,c.relativeTimeRounding=function(e){return void 0===e?Un:"function"==typeof e&&(Un=e,!0)},c.relativeTimeThreshold=function(e,t){return void 0!==Nn[e]&&(void 0===t?Nn[e]:(Nn[e]=t,"s"===e&&(Nn.ss=t-1),!0))},c.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},c.prototype=ln,c.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:"YYYY-[W]WW",MONTH:"YYYY-MM"},c}); \ No newline at end of file
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function c(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function l(e){return void 0===e}function h(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function d(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function f(e,t){var n,s=[];for(n=0;n<e.length;++n)s.push(t(e[n],n));return s}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function _(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function y(e,t,n,s){return Tt(e,t,n,s,!0).utc()}function g(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function v(e){if(null==e._isValid){var t=g(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function p(e){var t=y(NaN);return null!=e?_(g(t),e):g(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var r=c.momentProperties=[];function w(e,t){var n,s,i;if(l(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),l(t._i)||(e._i=t._i),l(t._f)||(e._f=t._f),l(t._l)||(e._l=t._l),l(t._strict)||(e._strict=t._strict),l(t._tzm)||(e._tzm=t._tzm),l(t._isUTC)||(e._isUTC=t._isUTC),l(t._offset)||(e._offset=t._offset),l(t._pf)||(e._pf=g(t)),l(t._locale)||(e._locale=t._locale),0<r.length)for(n=0;n<r.length;n++)l(i=t[s=r[n]])||(e[s]=i);return e}var t=!1;function M(e){w(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,c.updateOffset(this),t=!1)}function k(e){return e instanceof M||null!=e&&null!=e._isAMomentObject}function S(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function D(e){var t=+e,n=0;return 0!==t&&isFinite(t)&&(n=S(t)),n}function a(e,t,n){var s,i=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),a=0;for(s=0;s<i;s++)(n&&e[s]!==t[s]||!n&&D(e[s])!==D(t[s]))&&a++;return a+r}function Y(e){!1===c.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return _(function(){if(null!=c.deprecationHandler&&c.deprecationHandler(null,i),a){for(var e,t=[],n=0;n<arguments.length;n++){if(e="","object"==typeof arguments[n]){for(var s in e+="\n["+n+"] ",arguments[0])e+=s+": "+arguments[0][s]+", ";e=e.slice(0,-2)}else e=arguments[n];t.push(e)}Y(i+"\nArguments: "+Array.prototype.slice.call(t).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,O={};function T(e,t){null!=c.deprecationHandler&&c.deprecationHandler(e,t),O[e]||(Y(t),O[e]=!0)}function b(e){return e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function x(e,t){var n,s=_({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},_(s[n],e[n]),_(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=_({},s[n]));return s}function P(e){null!=e&&this.set(e)}c.suppressDeprecationWarnings=!1,c.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};var W={};function C(e,t){var n=e.toLowerCase();W[n]=W[n+"s"]=W[t]=e}function H(e){return"string"==typeof e?W[e]||W[e.toLowerCase()]:void 0}function R(e){var t,n,s={};for(n in e)m(e,n)&&(t=H(n))&&(s[t]=e[n]);return s}var U={};function F(e,t){U[e]=t}function L(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,G=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,V={},E={};function I(e,t,n,s){var i=s;"string"==typeof s&&(i=function(){return this[s]()}),e&&(E[e]=i),t&&(E[t[0]]=function(){return L(i.apply(this,arguments),t[1],t[2])}),n&&(E[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function A(e,t){return e.isValid()?(t=j(t,e.localeData()),V[t]=V[t]||function(s){var e,i,t,r=s.match(N);for(e=0,i=r.length;e<i;e++)E[r[e]]?r[e]=E[r[e]]:r[e]=(t=r[e]).match(/\[[\s\S]/)?t.replace(/^\[|\]$/g,""):t.replace(/\\/g,"");return function(e){var t,n="";for(t=0;t<i;t++)n+=b(r[t])?r[t].call(e,s):r[t];return n}}(t),V[t](e)):e.localeData().invalidDate()}function j(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(G.lastIndex=0;0<=n&&G.test(e);)e=e.replace(G,s),G.lastIndex=0,n-=1;return e}var Z=/\d/,z=/\d\d/,$=/\d{3}/,q=/\d{4}/,J=/[+-]?\d{6}/,B=/\d\d?/,Q=/\d\d\d\d?/,X=/\d\d\d\d\d\d?/,K=/\d{1,3}/,ee=/\d{1,4}/,te=/[+-]?\d{1,6}/,ne=/\d+/,se=/[+-]?\d+/,ie=/Z|[+-]\d\d:?\d\d/gi,re=/Z|[+-]\d\d(?::?\d\d)?/gi,ae=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,oe={};function ue(e,n,s){oe[e]=b(n)?n:function(e,t){return e&&s?s:n}}function le(e,t){return m(oe,e)?oe[e](t._strict,t._locale):new RegExp(he(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function he(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var de={};function ce(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),h(n)&&(s=function(e,t){t[n]=D(e)}),t=0;t<e.length;t++)de[e[t]]=s}function fe(e,i){ce(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var me=0,_e=1,ye=2,ge=3,ve=4,pe=5,we=6,Me=7,ke=8;function Se(e){return De(e)?366:365}function De(e){return e%4==0&&e%100!=0||e%400==0}I("Y",0,0,function(){var e=this.year();return e<=9999?""+e:"+"+e}),I(0,["YY",2],0,function(){return this.year()%100}),I(0,["YYYY",4],0,"year"),I(0,["YYYYY",5],0,"year"),I(0,["YYYYYY",6,!0],0,"year"),C("year","y"),F("year",1),ue("Y",se),ue("YY",B,z),ue("YYYY",ee,q),ue("YYYYY",te,J),ue("YYYYYY",te,J),ce(["YYYYY","YYYYYY"],me),ce("YYYY",function(e,t){t[me]=2===e.length?c.parseTwoDigitYear(e):D(e)}),ce("YY",function(e,t){t[me]=c.parseTwoDigitYear(e)}),ce("Y",function(e,t){t[me]=parseInt(e,10)}),c.parseTwoDigitYear=function(e){return D(e)+(68<D(e)?1900:2e3)};var Ye,Oe=Te("FullYear",!0);function Te(t,n){return function(e){return null!=e?(xe(this,t,e),c.updateOffset(this,n),this):be(this,t)}}function be(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function xe(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&De(e.year())&&1===e.month()&&29===e.date()?e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),Pe(n,e.month())):e._d["set"+(e._isUTC?"UTC":"")+t](n))}function Pe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1===s?De(e)?29:28:31-s%7%2}Ye=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;t<this.length;++t)if(this[t]===e)return t;return-1},I("M",["MM",2],"Mo",function(){return this.month()+1}),I("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),I("MMMM",0,0,function(e){return this.localeData().months(this,e)}),C("month","M"),F("month",8),ue("M",B),ue("MM",B,z),ue("MMM",function(e,t){return t.monthsShortRegex(e)}),ue("MMMM",function(e,t){return t.monthsRegex(e)}),ce(["M","MM"],function(e,t){t[_e]=D(e)-1}),ce(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[_e]=i:g(n).invalidMonth=e});var We=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Ce="January_February_March_April_May_June_July_August_September_October_November_December".split("_");var He="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_");function Re(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=D(t);else if(!h(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),Pe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Ue(e){return null!=e?(Re(this,e),c.updateOffset(this,!0),this):be(this,"Month")}var Fe=ae;var Le=ae;function Ne(){function e(e,t){return t.length-e.length}var t,n,s=[],i=[],r=[];for(t=0;t<12;t++)n=y([2e3,t]),s.push(this.monthsShort(n,"")),i.push(this.months(n,"")),r.push(this.months(n,"")),r.push(this.monthsShort(n,""));for(s.sort(e),i.sort(e),r.sort(e),t=0;t<12;t++)s[t]=he(s[t]),i[t]=he(i[t]);for(t=0;t<24;t++)r[t]=he(r[t]);this._monthsRegex=new RegExp("^("+r.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+s.join("|")+")","i")}function Ge(e){var t;if(e<100&&0<=e){var n=Array.prototype.slice.call(arguments);n[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)}else t=new Date(Date.UTC.apply(null,arguments));return t}function Ve(e,t,n){var s=7+t-n;return-((7+Ge(e,0,s).getUTCDay()-t)%7)+s-1}function Ee(e,t,n,s,i){var r,a,o=1+7*(t-1)+(7+n-s)%7+Ve(e,s,i);return a=o<=0?Se(r=e-1)+o:o>Se(e)?(r=e+1,o-Se(e)):(r=e,o),{year:r,dayOfYear:a}}function Ie(e,t,n){var s,i,r=Ve(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+Ae(i=e.year()-1,t,n):a>Ae(e.year(),t,n)?(s=a-Ae(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function Ae(e,t,n){var s=Ve(e,t,n),i=Ve(e+1,t,n);return(Se(e)-s+i)/7}I("w",["ww",2],"wo","week"),I("W",["WW",2],"Wo","isoWeek"),C("week","w"),C("isoWeek","W"),F("week",5),F("isoWeek",5),ue("w",B),ue("ww",B,z),ue("W",B),ue("WW",B,z),fe(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=D(e)});function je(e,t){return e.slice(t,7).concat(e.slice(0,t))}I("d",0,"do","day"),I("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),I("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),I("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),I("e",0,0,"weekday"),I("E",0,0,"isoWeekday"),C("day","d"),C("weekday","e"),C("isoWeekday","E"),F("day",11),F("weekday",11),F("isoWeekday",11),ue("d",B),ue("e",B),ue("E",B),ue("dd",function(e,t){return t.weekdaysMinRegex(e)}),ue("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ue("dddd",function(e,t){return t.weekdaysRegex(e)}),fe(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:g(n).invalidWeekday=e}),fe(["d","e","E"],function(e,t,n,s){t[s]=D(e)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_");var ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_");var $e="Su_Mo_Tu_We_Th_Fr_Sa".split("_");var qe=ae;var Je=ae;var Be=ae;function Qe(){function e(e,t){return t.length-e.length}var t,n,s,i,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=y([2e3,1]).day(t),s=this.weekdaysMin(n,""),i=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(s),o.push(i),u.push(r),l.push(s),l.push(i),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=he(o[t]),u[t]=he(u[t]),l[t]=he(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function Xe(){return this.hours()%12||12}function Ke(e,t){I(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function et(e,t){return t._meridiemParse}I("H",["HH",2],0,"hour"),I("h",["hh",2],0,Xe),I("k",["kk",2],0,function(){return this.hours()||24}),I("hmm",0,0,function(){return""+Xe.apply(this)+L(this.minutes(),2)}),I("hmmss",0,0,function(){return""+Xe.apply(this)+L(this.minutes(),2)+L(this.seconds(),2)}),I("Hmm",0,0,function(){return""+this.hours()+L(this.minutes(),2)}),I("Hmmss",0,0,function(){return""+this.hours()+L(this.minutes(),2)+L(this.seconds(),2)}),Ke("a",!0),Ke("A",!1),C("hour","h"),F("hour",13),ue("a",et),ue("A",et),ue("H",B),ue("h",B),ue("k",B),ue("HH",B,z),ue("hh",B,z),ue("kk",B,z),ue("hmm",Q),ue("hmmss",X),ue("Hmm",Q),ue("Hmmss",X),ce(["H","HH"],ge),ce(["k","kk"],function(e,t,n){var s=D(e);t[ge]=24===s?0:s}),ce(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ce(["h","hh"],function(e,t,n){t[ge]=D(e),g(n).bigHour=!0}),ce("hmm",function(e,t,n){var s=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s)),g(n).bigHour=!0}),ce("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s,2)),t[pe]=D(e.substr(i)),g(n).bigHour=!0}),ce("Hmm",function(e,t,n){var s=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s))}),ce("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[ge]=D(e.substr(0,s)),t[ve]=D(e.substr(s,2)),t[pe]=D(e.substr(i))});var tt,nt=Te("Hours",!0),st={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{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"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,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"},months:Ce,monthsShort:He,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:$e,weekdaysShort:ze,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){var t=null;if(!it[e]&&"undefined"!=typeof module&&module&&module.exports)try{t=tt._abbr,require("./locale/"+e),ut(t)}catch(e){}return it[e]}function ut(e,t){var n;return e&&((n=l(t)?ht(e):lt(e,t))?tt=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),tt._abbr}function lt(e,t){if(null===t)return delete it[e],null;var n,s=st;if(t.abbr=e,null!=it[e])T("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."),s=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])s=it[t.parentLocale]._config;else{if(null==(n=ot(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return it[e]=new P(x(s,t)),rt[e]&&rt[e].forEach(function(e){lt(e.name,e.config)}),ut(e),it[e]}function ht(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return tt;if(!o(e)){if(t=ot(e))return t;e=[e]}return function(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=at(e[r]).split("-")).length,n=(n=at(e[r+1]))?n.split("-"):null;0<t;){if(s=ot(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&a(i,n,!0)>=t-1)break;t--}r++}return tt}(e)}function dt(e){var t,n=e._a;return n&&-2===g(e).overflow&&(t=n[_e]<0||11<n[_e]?_e:n[ye]<1||n[ye]>Pe(n[me],n[_e])?ye:n[ge]<0||24<n[ge]||24===n[ge]&&(0!==n[ve]||0!==n[pe]||0!==n[we])?ge:n[ve]<0||59<n[ve]?ve:n[pe]<0||59<n[pe]?pe:n[we]<0||999<n[we]?we:-1,g(e)._overflowDayOfYear&&(t<me||ye<t)&&(t=ye),g(e)._overflowWeeks&&-1===t&&(t=Me),g(e)._overflowWeekday&&-1===t&&(t=ke),g(e).overflow=t),e}function ct(e,t,n){return null!=e?e:null!=t?t:n}function ft(e){var t,n,s,i,r,a=[];if(!e._d){var o,u;for(o=e,u=new Date(c.now()),s=o._useUTC?[u.getUTCFullYear(),u.getUTCMonth(),u.getUTCDate()]:[u.getFullYear(),u.getMonth(),u.getDate()],e._w&&null==e._a[ye]&&null==e._a[_e]&&function(e){var t,n,s,i,r,a,o,u;if(null!=(t=e._w).GG||null!=t.W||null!=t.E)r=1,a=4,n=ct(t.GG,e._a[me],Ie(bt(),1,4).year),s=ct(t.W,1),((i=ct(t.E,1))<1||7<i)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=Ie(bt(),r,a);n=ct(t.gg,e._a[me],l.year),s=ct(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r}s<1||s>Ae(n,r,a)?g(e)._overflowWeeks=!0:null!=u?g(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[me]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=ct(e._a[me],s[me]),(e._dayOfYear>Se(r)||0===e._dayOfYear)&&(g(e)._overflowDayOfYear=!0),n=Ge(r,0,e._dayOfYear),e._a[_e]=n.getUTCMonth(),e._a[ye]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=s[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[ge]&&0===e._a[ve]&&0===e._a[pe]&&0===e._a[we]&&(e._nextDay=!0,e._a[ge]=0),e._d=(e._useUTC?Ge:function(e,t,n,s,i,r,a){var o;return e<100&&0<=e?(o=new Date(e+400,t,n,s,i,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,s,i,r,a),o}).apply(null,a),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[ge]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(g(e).weekdayMismatch=!0)}}var mt=/^\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)?)?$/,_t=/^\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)?)?$/,yt=/Z|[+-]\d\d(?::?\d\d)?/,gt=[["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/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],vt=[["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/]],pt=/^\/?Date\((\-?\d+)/i;function wt(e){var t,n,s,i,r,a,o=e._i,u=mt.exec(o)||_t.exec(o);if(u){for(g(e).iso=!0,t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[1])){i=gt[t][0],s=!1!==gt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=vt.length;t<n;t++)if(vt[t][1].exec(u[3])){r=(u[2]||" ")+vt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!yt.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),Yt(e)}else e._isValid=!1}var Mt=/^(?:(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}))$/;function kt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),He.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}var St={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function Dt(e){var t,n,s,i=Mt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));if(i){var r=kt(i[4],i[3],i[2],i[5],i[6],i[7]);if(t=i[1],n=r,s=e,t&&ze.indexOf(t)!==new Date(n[0],n[1],n[2]).getDay()&&(g(s).weekdayMismatch=!0,!(s._isValid=!1)))return;e._a=r,e._tzm=function(e,t,n){if(e)return St[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return(s-i)/100*60+i}(i[8],i[9],i[10]),e._d=Ge.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),g(e).rfc2822=!0}else e._isValid=!1}function Yt(e){if(e._f!==c.ISO_8601)if(e._f!==c.RFC_2822){e._a=[],g(e).empty=!0;var t,n,s,i,r,a,o,u,l=""+e._i,h=l.length,d=0;for(s=j(e._f,e._locale).match(N)||[],t=0;t<s.length;t++)i=s[t],(n=(l.match(le(i,e))||[])[0])&&(0<(r=l.substr(0,l.indexOf(n))).length&&g(e).unusedInput.push(r),l=l.slice(l.indexOf(n)+n.length),d+=n.length),E[i]?(n?g(e).empty=!1:g(e).unusedTokens.push(i),a=i,u=e,null!=(o=n)&&m(de,a)&&de[a](o,u._a,u,a)):e._strict&&!n&&g(e).unusedTokens.push(i);g(e).charsLeftOver=h-d,0<l.length&&g(e).unusedInput.push(l),e._a[ge]<=12&&!0===g(e).bigHour&&0<e._a[ge]&&(g(e).bigHour=void 0),g(e).parsedDateParts=e._a.slice(0),g(e).meridiem=e._meridiem,e._a[ge]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[ge],e._meridiem),ft(e),dt(e)}else Dt(e);else wt(e)}function Ot(e){var t,n,s,i,r=e._i,a=e._f;return e._locale=e._locale||ht(e._l),null===r||void 0===a&&""===r?p({nullInput:!0}):("string"==typeof r&&(e._i=r=e._locale.preparse(r)),k(r)?new M(dt(r)):(d(r)?e._d=r:o(a)?function(e){var t,n,s,i,r;if(0===e._f.length)return g(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,t=w({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],Yt(t),v(t)&&(r+=g(t).charsLeftOver,r+=10*g(t).unusedTokens.length,g(t).score=r,(null==s||r<s)&&(s=r,n=t));_(e,n||t)}(e):a?Yt(e):l(n=(t=e)._i)?t._d=new Date(c.now()):d(n)?t._d=new Date(n.valueOf()):"string"==typeof n?(s=t,null===(i=pt.exec(s._i))?(wt(s),!1===s._isValid&&(delete s._isValid,Dt(s),!1===s._isValid&&(delete s._isValid,c.createFromInputFallback(s)))):s._d=new Date(+i[1])):o(n)?(t._a=f(n.slice(0),function(e){return parseInt(e,10)}),ft(t)):u(n)?function(e){if(!e._d){var t=R(e._i);e._a=f([t.year,t.month,t.day||t.date,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),ft(e)}}(t):h(n)?t._d=new Date(n):c.createFromInputFallback(t),v(e)||(e._d=null),e))}function Tt(e,t,n,s,i){var r,a={};return!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&function(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;var t;for(t in e)if(e.hasOwnProperty(t))return!1;return!0}(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new M(dt(Ot(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function bt(e,t,n,s){return Tt(e,t,n,s,!1)}c.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),c.ISO_8601=function(){},c.RFC_2822=function(){};var xt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=bt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:p()}),Pt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=bt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:p()});function Wt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return bt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Ct=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ht(e){var t=R(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||t.isoWeek||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,h=t.millisecond||0;this._isValid=function(e){for(var t in e)if(-1===Ye.call(Ct,t)||null!=e[t]&&isNaN(e[t]))return!1;for(var n=!1,s=0;s<Ct.length;++s)if(e[Ct[s]]){if(n)return!1;parseFloat(e[Ct[s]])!==D(e[Ct[s]])&&(n=!0)}return!0}(t),this._milliseconds=+h+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=ht(),this._bubble()}function Rt(e){return e instanceof Ht}function Ut(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){I(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+L(~~(e/60),2)+n+L(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ue("Z",re),ue("ZZ",re),ce(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Nt(re,e)});var Lt=/([\+\-]|\d\d)/gi;function Nt(e,t){var n=(t||"").match(e);if(null===n)return null;var s=((n[n.length-1]||[])+"").match(Lt)||["-",0,0],i=60*s[1]+D(s[2]);return 0===i?0:"+"===s[0]?i:-i}function Gt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(k(e)||d(e)?e.valueOf():bt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),c.updateOffset(n,!1),n):bt(e).local()}function Vt(e){return 15*-Math.round(e._d.getTimezoneOffset()/15)}function Et(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}c.updateOffset=function(){};var It=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,At=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function jt(e,t){var n,s,i,r=e,a=null;return Rt(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:h(e)?(r={},t?r[t]=e:r.milliseconds=e):(a=It.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:D(a[ye])*n,h:D(a[ge])*n,m:D(a[ve])*n,s:D(a[pe])*n,ms:D(Ut(1e3*a[we]))*n}):(a=At.exec(e))?(n="-"===a[1]?-1:1,r={y:Zt(a[2],n),M:Zt(a[3],n),w:Zt(a[4],n),d:Zt(a[5],n),h:Zt(a[6],n),m:Zt(a[7],n),s:Zt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Gt(t,e),e.isBefore(t)?n=zt(e,t):((n=zt(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(bt(r.from),bt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ht(r),Rt(e)&&m(e,"_locale")&&(s._locale=e._locale),s}function Zt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function zt(e,t){var n={};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function $t(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(T(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),qt(this,jt(e="string"==typeof e?+e:e,t),s),this}}function qt(e,t,n,s){var i=t._milliseconds,r=Ut(t._days),a=Ut(t._months);e.isValid()&&(s=null==s||s,a&&Re(e,be(e,"Month")+a*n),r&&xe(e,"Date",be(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&c.updateOffset(e,r||a))}jt.fn=Ht.prototype,jt.invalid=function(){return jt(NaN)};var Jt=$t(1,"add"),Bt=$t(-1,"subtract");function Qt(e,t){var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months");return-(n+(t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(n+1,"months")-s)))||0}function Xt(e){var t;return void 0===e?this._locale._abbr:(null!=(t=ht(e))&&(this._locale=t),this)}c.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",c.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var Kt=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function en(){return this._locale}var tn=126227808e5;function nn(e,t){return(e%t+t)%t}function sn(e,t,n){return e<100&&0<=e?new Date(e+400,t,n)-tn:new Date(e,t,n).valueOf()}function rn(e,t,n){return e<100&&0<=e?Date.UTC(e+400,t,n)-tn:Date.UTC(e,t,n)}function an(e,t){I(0,[e,e.length],0,t)}function on(e,t,n,s,i){var r;return null==e?Ie(this,s,i).year:((r=Ae(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ge(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}I(0,["gg",2],0,function(){return this.weekYear()%100}),I(0,["GG",2],0,function(){return this.isoWeekYear()%100}),an("gggg","weekYear"),an("ggggg","weekYear"),an("GGGG","isoWeekYear"),an("GGGGG","isoWeekYear"),C("weekYear","gg"),C("isoWeekYear","GG"),F("weekYear",1),F("isoWeekYear",1),ue("G",se),ue("g",se),ue("GG",B,z),ue("gg",B,z),ue("GGGG",ee,q),ue("gggg",ee,q),ue("GGGGG",te,J),ue("ggggg",te,J),fe(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=D(e)}),fe(["gg","GG"],function(e,t,n,s){t[s]=c.parseTwoDigitYear(e)}),I("Q",0,"Qo","quarter"),C("quarter","Q"),F("quarter",7),ue("Q",Z),ce("Q",function(e,t){t[_e]=3*(D(e)-1)}),I("D",["DD",2],"Do","date"),C("date","D"),F("date",9),ue("D",B),ue("DD",B,z),ue("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ce(["D","DD"],ye),ce("Do",function(e,t){t[ye]=D(e.match(B)[0])});var un=Te("Date",!0);I("DDD",["DDDD",3],"DDDo","dayOfYear"),C("dayOfYear","DDD"),F("dayOfYear",4),ue("DDD",K),ue("DDDD",$),ce(["DDD","DDDD"],function(e,t,n){n._dayOfYear=D(e)}),I("m",["mm",2],0,"minute"),C("minute","m"),F("minute",14),ue("m",B),ue("mm",B,z),ce(["m","mm"],ve);var ln=Te("Minutes",!1);I("s",["ss",2],0,"second"),C("second","s"),F("second",15),ue("s",B),ue("ss",B,z),ce(["s","ss"],pe);var hn,dn=Te("Seconds",!1);for(I("S",0,0,function(){return~~(this.millisecond()/100)}),I(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),I(0,["SSS",3],0,"millisecond"),I(0,["SSSS",4],0,function(){return 10*this.millisecond()}),I(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),I(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),I(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),I(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),I(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),C("millisecond","ms"),F("millisecond",16),ue("S",K,Z),ue("SS",K,z),ue("SSS",K,$),hn="SSSS";hn.length<=9;hn+="S")ue(hn,ne);function cn(e,t){t[we]=D(1e3*("0."+e))}for(hn="S";hn.length<=9;hn+="S")ce(hn,cn);var fn=Te("Milliseconds",!1);I("z",0,0,"zoneAbbr"),I("zz",0,0,"zoneName");var mn=M.prototype;function _n(e){return e}mn.add=Jt,mn.calendar=function(e,t){var n=e||bt(),s=Gt(n,this).startOf("day"),i=c.calendarFormat(this,s)||"sameElse",r=t&&(b(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,bt(n)))},mn.clone=function(){return new M(this)},mn.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Gt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=H(t)){case"year":r=Qt(this,s)/12;break;case"month":r=Qt(this,s);break;case"quarter":r=Qt(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:S(r)},mn.endOf=function(e){var t;if(void 0===(e=H(e))||"millisecond"===e||!this.isValid())return this;var n=this._isUTC?rn:sn;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+=36e5-nn(t+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":t=this._d.valueOf(),t+=6e4-nn(t,6e4)-1;break;case"second":t=this._d.valueOf(),t+=1e3-nn(t,1e3)-1;break}return this._d.setTime(t),c.updateOffset(this,!0),this},mn.format=function(e){e||(e=this.isUtc()?c.defaultFormatUtc:c.defaultFormat);var t=A(this,e);return this.localeData().postformat(t)},mn.from=function(e,t){return this.isValid()&&(k(e)&&e.isValid()||bt(e).isValid())?jt({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},mn.fromNow=function(e){return this.from(bt(),e)},mn.to=function(e,t){return this.isValid()&&(k(e)&&e.isValid()||bt(e).isValid())?jt({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},mn.toNow=function(e){return this.to(bt(),e)},mn.get=function(e){return b(this[e=H(e)])?this[e]():this},mn.invalidAt=function(){return g(this).overflow},mn.isAfter=function(e,t){var n=k(e)?e:bt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=H(t)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},mn.isBefore=function(e,t){var n=k(e)?e:bt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=H(t)||"millisecond")?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},mn.isBetween=function(e,t,n,s){var i=k(e)?e:bt(e),r=k(t)?t:bt(t);return!!(this.isValid()&&i.isValid()&&r.isValid())&&("("===(s=s||"()")[0]?this.isAfter(i,n):!this.isBefore(i,n))&&(")"===s[1]?this.isBefore(r,n):!this.isAfter(r,n))},mn.isSame=function(e,t){var n,s=k(e)?e:bt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=H(t)||"millisecond")?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},mn.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},mn.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},mn.isValid=function(){return v(this)},mn.lang=Kt,mn.locale=Xt,mn.localeData=en,mn.max=Pt,mn.min=xt,mn.parsingFlags=function(){return _({},g(this))},mn.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t=[];for(var n in e)t.push({unit:n,priority:U[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}(e=R(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(b(this[e=H(e)]))return this[e](t);return this},mn.startOf=function(e){var t;if(void 0===(e=H(e))||"millisecond"===e||!this.isValid())return this;var n=this._isUTC?rn:sn;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-=nn(t+(this._isUTC?0:6e4*this.utcOffset()),36e5);break;case"minute":t=this._d.valueOf(),t-=nn(t,6e4);break;case"second":t=this._d.valueOf(),t-=nn(t,1e3);break}return this._d.setTime(t),c.updateOffset(this,!0),this},mn.subtract=Bt,mn.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},mn.toObject=function(){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()}},mn.toDate=function(){return new Date(this.valueOf())},mn.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?A(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):b(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",A(n,"Z")):A(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},mn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',s=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",i=t+'[")]';return this.format(n+s+"-MM-DD[T]HH:mm:ss.SSS"+i)},mn.toJSON=function(){return this.isValid()?this.toISOString():null},mn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},mn.unix=function(){return Math.floor(this.valueOf()/1e3)},mn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},mn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},mn.year=Oe,mn.isLeapYear=function(){return De(this.year())},mn.weekYear=function(e){return on.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},mn.isoWeekYear=function(e){return on.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},mn.quarter=mn.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},mn.month=Ue,mn.daysInMonth=function(){return Pe(this.year(),this.month())},mn.week=mn.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},mn.isoWeek=mn.isoWeeks=function(e){var t=Ie(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},mn.weeksInYear=function(){var e=this.localeData()._week;return Ae(this.year(),e.dow,e.doy)},mn.isoWeeksInYear=function(){return Ae(this.year(),1,4)},mn.date=un,mn.day=mn.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},mn.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},mn.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null==e)return this.day()||7;var t,n,s=(t=e,n=this.localeData(),"string"==typeof t?n.weekdaysParse(t)%7||7:isNaN(t)?null:t);return this.day(this.day()%7?s:s-7)},mn.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},mn.hour=mn.hours=nt,mn.minute=mn.minutes=ln,mn.second=mn.seconds=dn,mn.millisecond=mn.milliseconds=fn,mn.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null==e)return this._isUTC?i:Vt(this);if("string"==typeof e){if(null===(e=Nt(re,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Vt(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?qt(this,jt(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,c.updateOffset(this,!0),this._changeInProgress=null)),this},mn.utc=function(e){return this.utcOffset(0,e)},mn.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Vt(this),"m")),this},mn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var e=Nt(ie,this._i);null!=e?this.utcOffset(e):this.utcOffset(0,!0)}return this},mn.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?bt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},mn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},mn.isLocal=function(){return!!this.isValid()&&!this._isUTC},mn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},mn.isUtc=Et,mn.isUTC=Et,mn.zoneAbbr=function(){return this._isUTC?"UTC":""},mn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},mn.dates=n("dates accessor is deprecated. Use date instead.",un),mn.months=n("months accessor is deprecated. Use month instead",Ue),mn.years=n("years accessor is deprecated. Use year instead",Oe),mn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),mn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!l(this._isDSTShifted))return this._isDSTShifted;var e={};if(w(e,this),(e=Ot(e))._a){var t=e._isUTC?y(e._a):bt(e._a);this._isDSTShifted=this.isValid()&&0<a(e._a,t.toArray())}else this._isDSTShifted=!1;return this._isDSTShifted});var yn=P.prototype;function gn(e,t,n,s){var i=ht(),r=y().set(s,t);return i[n](r,e)}function vn(e,t,n){if(h(e)&&(t=e,e=void 0),e=e||"",null!=t)return gn(e,t,n,"month");var s,i=[];for(s=0;s<12;s++)i[s]=gn(e,s,n,"month");return i}function pn(e,t,n,s){t=("boolean"==typeof e?h(t)&&(n=t,t=void 0):(t=e,e=!1,h(n=t)&&(n=t,t=void 0)),t||"");var i,r=ht(),a=e?r._week.dow:0;if(null!=n)return gn(t,(n+a)%7,s,"day");var o=[];for(i=0;i<7;i++)o[i]=gn(t,(i+a)%7,s,"day");return o}yn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return b(s)?s.call(t,n):s},yn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e])},yn.invalidDate=function(){return this._invalidDate},yn.ordinal=function(e){return this._ordinal.replace("%d",e)},yn.preparse=_n,yn.postformat=_n,yn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return b(i)?i(e,t,n,s):i.replace(/%d/i,e)},yn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return b(n)?n(t):n.replace(/%s/i,t)},yn.set=function(e){var t,n;for(n in e)b(t=e[n])?this[n]=t:this["_"+n]=t;this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},yn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||We).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},yn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[We.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},yn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=y([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=Ye.call(this._shortMonthsParse,a))?i:-1!==(i=Ye.call(this._longMonthsParse,a))?i:null:-1!==(i=Ye.call(this._longMonthsParse,a))?i:-1!==(i=Ye.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=y([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},yn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=Le),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},yn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||Ne.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Fe),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},yn.week=function(e){return Ie(e,this._week.dow,this._week.doy).week},yn.firstDayOfYear=function(){return this._week.doy},yn.firstDayOfWeek=function(){return this._week.dow},yn.weekdays=function(e,t){var n=o(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?je(n,this._week.dow):e?n[e.day()]:n},yn.weekdaysMin=function(e){return!0===e?je(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},yn.weekdaysShort=function(e){return!0===e?je(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},yn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=y([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:null:-1!==(i=Ye.call(this._minWeekdaysParse,a))?i:-1!==(i=Ye.call(this._weekdaysParse,a))?i:-1!==(i=Ye.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=y([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},yn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=qe),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},yn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Je),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},yn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Be),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},yn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},yn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},ut("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===D(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),c.lang=n("moment.lang is deprecated. Use moment.locale instead.",ut),c.langData=n("moment.langData is deprecated. Use moment.localeData instead.",ht);var wn=Math.abs;function Mn(e,t,n,s){var i=jt(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function kn(e){return e<0?Math.floor(e):Math.ceil(e)}function Sn(e){return 4800*e/146097}function Dn(e){return 146097*e/4800}function Yn(e){return function(){return this.as(e)}}var On=Yn("ms"),Tn=Yn("s"),bn=Yn("m"),xn=Yn("h"),Pn=Yn("d"),Wn=Yn("w"),Cn=Yn("M"),Hn=Yn("Q"),Rn=Yn("y");function Un(e){return function(){return this.isValid()?this._data[e]:NaN}}var Fn=Un("milliseconds"),Ln=Un("seconds"),Nn=Un("minutes"),Gn=Un("hours"),Vn=Un("days"),En=Un("months"),In=Un("years");var An=Math.round,jn={ss:44,s:45,m:45,h:22,d:26,M:11};var Zn=Math.abs;function zn(e){return(0<e)-(e<0)||+e}function $n(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n=Zn(this._milliseconds)/1e3,s=Zn(this._days),i=Zn(this._months);t=S((e=S(n/60))/60),n%=60,e%=60;var r=S(i/12),a=i%=12,o=s,u=t,l=e,h=n?n.toFixed(3).replace(/\.?0+$/,""):"",d=this.asSeconds();if(!d)return"P0D";var c=d<0?"-":"",f=zn(this._months)!==zn(d)?"-":"",m=zn(this._days)!==zn(d)?"-":"",_=zn(this._milliseconds)!==zn(d)?"-":"";return c+"P"+(r?f+r+"Y":"")+(a?f+a+"M":"")+(o?m+o+"D":"")+(u||l||h?"T":"")+(u?_+u+"H":"")+(l?_+l+"M":"")+(h?_+h+"S":"")}var qn=Ht.prototype;return qn.isValid=function(){return this._isValid},qn.abs=function(){var e=this._data;return this._milliseconds=wn(this._milliseconds),this._days=wn(this._days),this._months=wn(this._months),e.milliseconds=wn(e.milliseconds),e.seconds=wn(e.seconds),e.minutes=wn(e.minutes),e.hours=wn(e.hours),e.months=wn(e.months),e.years=wn(e.years),this},qn.add=function(e,t){return Mn(this,e,t,1)},qn.subtract=function(e,t){return Mn(this,e,t,-1)},qn.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=H(e))||"quarter"===e||"year"===e)switch(t=this._days+s/864e5,n=this._months+Sn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(Dn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},qn.asMilliseconds=On,qn.asSeconds=Tn,qn.asMinutes=bn,qn.asHours=xn,qn.asDays=Pn,qn.asWeeks=Wn,qn.asMonths=Cn,qn.asQuarters=Hn,qn.asYears=Rn,qn.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*D(this._months/12):NaN},qn._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*kn(Dn(o)+a),o=a=0),u.milliseconds=r%1e3,e=S(r/1e3),u.seconds=e%60,t=S(e/60),u.minutes=t%60,n=S(t/60),u.hours=n%24,o+=i=S(Sn(a+=S(n/24))),a-=kn(Dn(i)),s=S(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},qn.clone=function(){return jt(this)},qn.get=function(e){return e=H(e),this.isValid()?this[e+"s"]():NaN},qn.milliseconds=Fn,qn.seconds=Ln,qn.minutes=Nn,qn.hours=Gn,qn.days=Vn,qn.weeks=function(){return S(this.days()/7)},qn.months=En,qn.years=In,qn.humanize=function(e){if(!this.isValid())return this.localeData().invalidDate();var t,n,s,i,r,a,o,u,l,h,d,c=this.localeData(),f=(n=!e,s=c,i=jt(t=this).abs(),r=An(i.as("s")),a=An(i.as("m")),o=An(i.as("h")),u=An(i.as("d")),l=An(i.as("M")),h=An(i.as("y")),(d=r<=jn.ss&&["s",r]||r<jn.s&&["ss",r]||a<=1&&["m"]||a<jn.m&&["mm",a]||o<=1&&["h"]||o<jn.h&&["hh",o]||u<=1&&["d"]||u<jn.d&&["dd",u]||l<=1&&["M"]||l<jn.M&&["MM",l]||h<=1&&["y"]||["yy",h])[2]=n,d[3]=0<+t,d[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,d));return e&&(f=c.pastFuture(+this,f)),c.postformat(f)},qn.toISOString=$n,qn.toString=$n,qn.toJSON=$n,qn.locale=Xt,qn.localeData=en,qn.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",$n),qn.lang=Kt,I("X",0,0,"unix"),I("x",0,0,"valueOf"),ue("x",se),ue("X",/[+-]?\d+(\.\d{1,3})?/),ce("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),ce("x",function(e,t,n){n._d=new Date(D(e))}),c.version="2.24.0",e=bt,c.fn=mn,c.min=function(){return Wt("isBefore",[].slice.call(arguments,0))},c.max=function(){return Wt("isAfter",[].slice.call(arguments,0))},c.now=function(){return Date.now?Date.now():+new Date},c.utc=y,c.unix=function(e){return bt(1e3*e)},c.months=function(e,t){return vn(e,t,"months")},c.isDate=d,c.locale=ut,c.invalid=p,c.duration=jt,c.isMoment=k,c.weekdays=function(e,t,n){return pn(e,t,n,"weekdays")},c.parseZone=function(){return bt.apply(null,arguments).parseZone()},c.localeData=ht,c.isDuration=Rt,c.monthsShort=function(e,t){return vn(e,t,"monthsShort")},c.weekdaysMin=function(e,t,n){return pn(e,t,n,"weekdaysMin")},c.defineLocale=lt,c.updateLocale=function(e,t){if(null!=t){var n,s,i=st;null!=(s=ot(e))&&(i=s._config),(n=new P(t=x(i,t))).parentLocale=it[e],it[e]=n,ut(e)}else null!=it[e]&&(null!=it[e].parentLocale?it[e]=it[e].parentLocale:null!=it[e]&&delete it[e]);return it[e]},c.locales=function(){return s(it)},c.weekdaysShort=function(e,t,n){return pn(e,t,n,"weekdaysShort")},c.normalizeUnits=H,c.relativeTimeRounding=function(e){return void 0===e?An:"function"==typeof e&&(An=e,!0)},c.relativeTimeThreshold=function(e,t){return void 0!==jn[e]&&(void 0===t?jn[e]:(jn[e]=t,"s"===e&&(jn.ss=t-1),!0))},c.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},c.prototype=mn,c.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"},c}); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js b/vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js
index c91126344..13ec307da 100644
--- a/vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js
+++ b/vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js
@@ -6,132 +6,132 @@
return true}function i(n,t){for(var r=-1,e=null==n?0:n.length,u=0,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[u++]=o)}return i}function o(n,t){return!(null==n||!n.length)&&-1<v(n,t,0)}function f(n,t,r){for(var e=-1,u=null==n?0:n.length;++e<u;)if(r(t,n[e]))return true;return false}function c(n,t){for(var r=-1,e=null==n?0:n.length,u=Array(e);++r<e;)u[r]=t(n[r],r,n);return u}function a(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];return n}function l(n,t,r,e){var u=-1,i=null==n?0:n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);
return r}function s(n,t,r,e){var u=null==n?0:n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r}function h(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(t(n[r],r,n))return true;return false}function p(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function _(n,t,r,e){var u=n.length;for(r+=e?1:-1;e?r--:++r<u;)if(t(n[r],r,n))return r;return-1}function v(n,t,r){if(t===t)n:{--r;for(var e=n.length;++r<e;)if(n[r]===t){n=r;break n}n=-1}else n=_(n,d,r);return n}function g(n,t,r,e){
--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function d(n){return n!==n}function y(n,t){var r=null==n?0:n.length;return r?m(n,t)/r:F}function b(n){return function(t){return null==t?T:t[n]}}function x(n){return function(t){return null==n?T:n[t]}}function j(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function w(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function m(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==T&&(r=r===T?i:r+i)}return r;
-}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function k(n,t){return c(t,function(t){return[t,n[t]]})}function E(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Ln[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
-}),r}function U(n,t){return function(r){return n(t(r))}}function B(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function L(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
-}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,kn="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",En=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+kn+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Un={};
-Un["[object Float32Array]"]=Un["[object Float64Array]"]=Un["[object Int8Array]"]=Un["[object Int16Array]"]=Un["[object Int32Array]"]=Un["[object Uint8Array]"]=Un["[object Uint8ClampedArray]"]=Un["[object Uint16Array]"]=Un["[object Uint32Array]"]=true,Un["[object Arguments]"]=Un["[object Array]"]=Un["[object ArrayBuffer]"]=Un["[object Boolean]"]=Un["[object DataView]"]=Un["[object Date]"]=Un["[object Error]"]=Un["[object Function]"]=Un["[object Map]"]=Un["[object Number]"]=Un["[object Object]"]=Un["[object RegExp]"]=Un["[object Set]"]=Un["[object String]"]=Un["[object WeakMap]"]=false;
-var Bn={};Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object DataView]"]=Bn["[object Boolean]"]=Bn["[object Date]"]=Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object Symbol]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,
-Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object WeakMap]"]=false;var Ln={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){
-try{var n=Nn&&Nn.require&&Nn.require("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e",
-"\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a",
-"\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I",
-"\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r",
-"\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ",
-"\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}),tt=x({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),rt=function x(mn){function An(n){if(yu(n)&&!ff(n)&&!(n instanceof Ln)){if(n instanceof On)return n;if(oi.call(n,"__wrapped__"))return Fe(n)}return new On(n)}function kn(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Ln(n){
-this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Fn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Fn;++t<r;)this.add(n[t]);
-}function Zn(n){this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=ff(n),u=!e&&of(n),i=!e&&!u&&af(n),o=!e&&!u&&!i&&_f(n),u=(e=e||u||i||o)?A(n.length,ni):[],f=u.length;for(r in n)!t&&!oi.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return De(Lr(n),pt(t,0,n.length))}function ut(n){return De(Lr(n))}function it(n,t,r){(r===T||lu(n[t],r))&&(r!==T||t in n)||st(n,t,r);
-}function ot(n,t,r){var e=n[t];oi.call(n,t)&&lu(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(lu(n[r][0],t))return r;return-1}function ct(n,t,r,e){return uo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,Wu(t),n)}function lt(n,t){return n&&Cr(t,Uu(t),n)}function st(n,t,r){"__proto__"==t&&Ai?Ai(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Ku(e),i=null==n;++r<e;)u[r]=i?T:Ru(n,t[r]);return u;
-}function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!du(n))return n;if(u=ff(n)){if(f=me(n),!c)return Lr(n,f)}else{var s=vo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(af(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Bn[s])return i?n:{};f=ke(n,s,c)}}if(o||(o=new Zn),
-i=o.get(n))return i;if(o.set(n,f),pf(n))return n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}),f;if(sf(n))return n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))}),f;var a=l?a?ve:_e:a?Uu:Wu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=Wu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Qu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ti("Expected a function");
-return bo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,E(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return uo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!wu(o):r(o,f)))var f=o,c=i;
-}return c}function jt(n,t){var r=[];return uo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Ee),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&oo(n,t,Wu)}function At(n,t){return n&&fo(n,t,Wu)}function kt(n,t){return i(t,function(t){return _u(n[t])})}function Et(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Me(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
-ff(n)?t:a(t,r(n))}function Ot(n){if(null==n)return n===T?"[object Undefined]":"[object Null]";if(mi&&mi in Qu(n)){var t=oi.call(n,mi),r=n[mi];try{n[mi]=T;var e=true}catch(n){}var u=ai.call(n);e&&(t?n[mi]=r:delete n[mi]),n=u}else n=ai.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&oi.call(n,t)}function zt(n,t){return null!=n&&t in Qu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Ku(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,E(t))),s=Ci(p.length,s),
-l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Ut(n,t,r,e){return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Bt(t,r,e){return r=Sr(r,t),t=2>r.length?t:Et(t,hr(r,0,-1)),r=null==t?t:t[Me(Ve(r))],null==r?T:n(r,t,e)}function Lt(n){return yu(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
-return yu(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return yu(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)return true;if(null==n||null==t||!yu(n)&&!yu(t))return n!==n&&t!==t;n:{var i=ff(n),o=ff(t),f=i?"[object Array]":vo(n),c=o?"[object Array]":vo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&af(n)){if(!af(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||_f(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
+}function A(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function E(n,t){return c(t,function(t){return[t,n[t]]})}function k(n){return function(t){return n(t)}}function S(n,t){return c(t,function(t){return n[t]})}function O(n,t){return n.has(t)}function I(n,t){for(var r=-1,e=n.length;++r<e&&-1<v(t,n[r],0););return r}function R(n,t){for(var r=n.length;r--&&-1<v(t,n[r],0););return r}function z(n){return"\\"+Un[n]}function W(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n];
+}),r}function B(n,t){return function(r){return n(t(r))}}function L(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r];o!==t&&"__lodash_placeholder__"!==o||(n[r]="__lodash_placeholder__",i[u++]=r)}return i}function U(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function C(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function D(n){if(Rn.test(n)){for(var t=On.lastIndex=0;On.test(n);)++t;n=t}else n=Qn(n);return n}function M(n){return Rn.test(n)?n.match(On)||[]:n.split("");
+}var T,$=1/0,F=NaN,N=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],P=/\b__p\+='';/g,Z=/\b(__p\+=)''\+/g,q=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39);/g,K=/[&<>"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={};
+Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false;
+var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true,
+Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){
+try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I",
+"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C",
+"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i",
+"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r",
+"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij",
+"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}),tt=x({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),rt=function x(mn){function An(n){if(yu(n)&&!ff(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(oi.call(n,"__wrapped__"))return Fe(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n,
+this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Tn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Fn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t<r;){var e=n[t];this.set(e[0],e[1])}}function Nn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Fn;++t<r;)this.add(n[t]);
+}function Zn(n){this.size=(this.__data__=new Tn(n)).size}function qn(n,t){var r,e=ff(n),u=!e&&of(n),i=!e&&!u&&af(n),o=!e&&!u&&!i&&_f(n),u=(e=e||u||i||o)?A(n.length,ni):[],f=u.length;for(r in n)!t&&!oi.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Se(r,f))||u.push(r);return u}function Qn(n){var t=n.length;return t?n[ir(0,t-1)]:T}function et(n,t){return De(Ur(n),pt(t,0,n.length))}function ut(n){return De(Ur(n))}function it(n,t,r){(r===T||lu(n[t],r))&&(r!==T||t in n)||st(n,t,r);
+}function ot(n,t,r){var e=n[t];oi.call(n,t)&&lu(e,r)&&(r!==T||t in n)||st(n,t,r)}function ft(n,t){for(var r=n.length;r--;)if(lu(n[r][0],t))return r;return-1}function ct(n,t,r,e){return uo(n,function(n,u,i){t(e,n,r(n),i)}),e}function at(n,t){return n&&Cr(t,Wu(t),n)}function lt(n,t){return n&&Cr(t,Bu(t),n)}function st(n,t,r){"__proto__"==t&&Ai?Ai(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function ht(n,t){for(var r=-1,e=t.length,u=Ku(e),i=null==n;++r<e;)u[r]=i?T:Ru(n,t[r]);return u;
+}function pt(n,t,r){return n===n&&(r!==T&&(n=n<=r?n:r),t!==T&&(n=n>=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!du(n))return n;if(u=ff(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=vo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(af(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn),
+i=o.get(n))return i;o.set(n,f),pf(n)?n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}):sf(n)&&n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))});var a=l?a?ve:_e:a?Bu:Wu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=Wu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Qu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ti("Expected a function");
+return bo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++u<l;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(a&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function bt(n,t){var r=true;return uo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function xt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===T?o===o&&!wu(o):r(o,f)))var f=o,c=i;
+}return c}function jt(n,t){var r=[];return uo(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function wt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=ke),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?wt(f,t-1,r,e,u):a(u,f):e||(u[u.length]=f)}return u}function mt(n,t){return n&&oo(n,t,Wu)}function At(n,t){return n&&fo(n,t,Wu)}function Et(n,t){return i(t,function(t){return _u(n[t])})}function kt(n,t){t=Sr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[Me(t[r++])];return r&&r==e?n:T}function St(n,t,r){return t=t(n),
+ff(n)?t:a(t,r(n))}function Ot(n){if(null==n)n=n===T?"[object Undefined]":"[object Null]";else if(mi&&mi in Qu(n)){var t=oi.call(n,mi),r=n[mi];try{n[mi]=T;var e=true}catch(n){}var u=ai.call(n);e&&(t?n[mi]=r:delete n[mi]),n=u}else n=ai.call(n);return n}function It(n,t){return n>t}function Rt(n,t){return null!=n&&oi.call(n,t)}function zt(n,t){return null!=n&&t in Qu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Ku(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ci(p.length,s),
+l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;if(v?!O(v,d):!e(h,d,r)){for(a=i;--a;){var y=l[a];if(y?!O(y,d):!e(n[a],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Bt(n,t,r){var e={};return mt(n,function(n,u,i){t(e,r(n),u,i)}),e}function Lt(t,r,e){return r=Sr(r,t),t=2>r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[Me(Ve(r))],null==r?T:n(r,t,e)}function Ut(n){return yu(n)&&"[object Arguments]"==Ot(n)}function Ct(n){
+return yu(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return yu(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!yu(n)&&!yu(t))t=n!==n&&t!==t;else n:{var i=ff(n),o=ff(t),f=i?"[object Array]":vo(n),c=o?"[object Array]":vo(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&af(n)){if(!af(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||_f(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{
if(!(1&r)&&(i=a&&oi.call(n,"__wrapped__"),f=o&&oi.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:oi.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++a<o;){var l=f[a],h=n[l],p=t[l];if(e)var _=i?e(p,h,l,t,n,u):e(h,p,l,n,t,u);if(_===T?h!==p&&!Mt(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l);
}c&&!s&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u.delete(n),u.delete(t),t=c}}else t=false;else t=false}}return t}function Tt(n){return yu(n)&&"[object Map]"==vo(n)}function $t(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=Qu(n);u--;){var f=r[u];if(o&&f[2]?f[1]!==n[f[0]]:!(f[0]in n))return false}for(;++u<i;){var f=r[u],c=f[0],a=n[c],l=f[1];if(o&&f[2]){if(a===T&&!(c in n))return false;
-}else{if(f=new Zn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!du(n)||ci&&ci in n)&&(_u(n)?hi:dn).test(Te(n))}function Nt(n){return yu(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return yu(n)&&"[object Set]"==vo(n)}function Zt(n){return yu(n)&&gu(n.length)&&!!Un[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?$u:typeof n=="object"?ff(n)?Jt(n[0],n[1]):Ht(n):Zu(n)}function Vt(n){if(!ze(n))return Bi(n);var t,r=[];for(t in Qu(n))oi.call(n,t)&&"constructor"!=t&&r.push(t);
-return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=su(n)?Ku(n.length):[];return uo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!du(t)?We(Me(n),t):function(r){var e=Ru(r,n);return e===T&&e===t?zu(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&oo(t,function(i,o){if(du(i)){u||(u=new Zn);var f=u,c=Be(n,o),a=Be(t,o),l=f.get(a);if(!l){var l=e?e(c,a,o+"",n,t,f):T,s=l===T;
-if(s){var h=ff(a),p=!h&&af(a),_=!h&&!p&&_f(a),l=a;h||p||_?ff(c)?l=c:hu(c)?l=Lr(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:xu(a)||of(a)?(l=c,of(c)?l=Ou(c):du(c)&&!_u(c)||(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a))}it(n,o,l)}else f=e?e(Be(n,o),i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Uu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[$u],E(ye())),n=Gt(n,function(n,r,u){return{a:c(t,function(t){return t(n)}),
-b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){if(e>=f){e=c;break n}e=c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return zu(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=Et(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return Et(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;for(n===t&&(t=Lr(t)),r&&(f=c(n,E(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&xi.call(f,a,1),
-xi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?xi.call(n,u,1):xr(n,u)}}return n}function ir(n,t){return n+Ii(Ti()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Ii(t/2))&&(n+=n);while(t);return r}function fr(n,t){return xo(Ue(n,t,$u),n+"")}function cr(n){return Qn(Lu(n))}function ar(n,t){var r=Lu(n);return De(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!du(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){
-var c=Me(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=du(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return De(Lu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Ku(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return uo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!wu(o)&&(r?o<=t:o<t)?e=i+1:u=i;
-}return u}return vr(n,t,$u,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=wu(t),a=t===T;u<i;){var l=Ii((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=wu(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ci(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){var o=n[r],f=t?t(o):o;if(!r||!lu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:wu(n)?F:+n}function yr(n){
-if(typeof n=="string")return n;if(ff(n))return c(n,yr)+"";if(wu(n))return ro?ro.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:so(n))return L(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),
-n=2>t.length?n:Et(n,hr(t,0,-1)),null==n||delete n[Me(Ve(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Ln&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Ku(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));return br(wt(i,1),t,r)}function Ar(n,t,r){
-for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function kr(n){return hu(n)?n:[]}function Er(n){return typeof n=="function"?n:$u}function Sr(n,t){return ff(n)?n:Ie(n,t)?[n]:jo(Iu(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=gi?gi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new vi(t).set(new vi(n)),t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length);
-}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=wu(n),o=t!==T,f=null===t,c=t===t,a=wu(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Ur(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Li(i-o,0),l=Ku(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];return l}function Br(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Li(i-f,0),s=Ku(l+a);
-for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Lr(n,t){var r=-1,e=n.length;for(t||(t=Ku(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,po(n),t)}function Mr(n,t){return Cr(n,_o(n),t)}function Tr(n,r){return function(e,u){var i=ff(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o);
-}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Qu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!su(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Qu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){var u=-1,i=Qu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break;
-}return t}}function Pr(n,t,r){function e(){return(this&&this!==$n&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Iu(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Mu(Du(t).replace(En,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:
-return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=eo(n.prototype),t=n.apply(r,t);return du(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Ku(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:B(f,a),o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==$n&&this instanceof u?i:t,this,f);
-}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Qu(t);if(!su(t)){var i=ye(r,3);t=Wu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ti("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?ho(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
-return function(){var n=arguments,e=n[0];if(o&&1==n.length&&ff(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Ku(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Ur(y,e,u,_)),i&&(y=Br(y,i,o,_)),d-=x,_&&d<a)return j=B(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ci(f.length,x),m=Lr(y);w--;){
-var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==$n&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Ut(r,n,t(e),{})}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
-return r=c(r,E(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Oi(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Ku(l+c),h=this&&this!==$n&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
-e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=Au(t),r===T?(r=t,t=0):r=Au(r),e=e===T?t<r?1:-1:Au(e);var u=-1;r=Li(Oi((r-t)/(e||1)),0);for(var i=Ku(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Su(t),r=Su(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&yo(r,u),r.placeholder=e,Le(r,n,t)}function ie(n){
-var t=Yu[n];return function(n,r){if(n=Su(n),r=null==r?0:Ci(ku(r),292)){var e=(Iu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Iu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=vo(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):k(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ti("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Li(ku(o),0),f=f===T?f:ku(f),a-=u?u.length:0,64&t){
-var l=e,s=u;e=u=T}var h=c?T:ho(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Ur(e,r,h[4]):r,i[4]=e?B(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Br(e,r,h[6]):r,i[6]=e?B(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ci(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1],
-r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Li(i[9]-a,0),!f&&24&t&&(t&=-25),c=t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),Le((h?co:yo)(c,i),n,t)}function ce(n,t,r,e){return n===T||lu(n,ei[r])&&!oi.call(e,r)?t:n}function ae(n,t,r,e,u,i){return du(n)&&du(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return xu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;
+}else{if(f=new Zn,e)var s=e(a,l,c,n,t,f);if(s===T?!Mt(l,a,3,e,f):!s)return false}}return true}function Ft(n){return!(!du(n)||ci&&ci in n)&&(_u(n)?hi:dn).test(Te(n))}function Nt(n){return yu(n)&&"[object RegExp]"==Ot(n)}function Pt(n){return yu(n)&&"[object Set]"==vo(n)}function Zt(n){return yu(n)&&gu(n.length)&&!!Bn[Ot(n)]}function qt(n){return typeof n=="function"?n:null==n?$u:typeof n=="object"?ff(n)?Jt(n[0],n[1]):Ht(n):Zu(n)}function Vt(n){if(!ze(n))return Li(n);var t,r=[];for(t in Qu(n))oi.call(n,t)&&"constructor"!=t&&r.push(t);
+return r}function Kt(n,t){return n<t}function Gt(n,t){var r=-1,e=su(n)?Ku(n.length):[];return uo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Ht(n){var t=xe(n);return 1==t.length&&t[0][2]?We(t[0][0],t[0][1]):function(r){return r===n||$t(r,n,t)}}function Jt(n,t){return Ie(n)&&t===t&&!du(t)?We(Me(n),t):function(r){var e=Ru(r,n);return e===T&&e===t?zu(r,n):Mt(t,e,3)}}function Yt(n,t,r,e,u){n!==t&&oo(t,function(i,o){if(u||(u=new Zn),du(i)){var f=u,c=Le(n,o),a=Le(t,o),l=f.get(a);if(l)it(n,o,l);else{
+var l=e?e(c,a,o+"",n,t,f):T,s=l===T;if(s){var h=ff(a),p=!h&&af(a),_=!h&&!p&&_f(a),l=a;h||p||_?ff(c)?l=c:hu(c)?l=Ur(c):p?(s=false,l=Ir(a,true)):_?(s=false,l=zr(a,true)):l=[]:xu(a)||of(a)?(l=c,of(c)?l=Ou(c):du(c)&&!_u(c)||(l=Ae(a))):s=false}s&&(f.set(a,l),Yt(l,a,r,e,f),f.delete(a)),it(n,o,l)}}else f=e?e(Le(n,o),i,o+"",n,t,u):T,f===T&&(f=i),it(n,o,f)},Bu)}function Qt(n,t){var r=n.length;if(r)return t+=0>t?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[$u],k(ye())),n=Gt(n,function(n){return{
+a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e<o;){var c=Wr(u[e],i[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return zu(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=kt(n,o);r(f,o)&&lr(i,Sr(o,n),f)}return i}function rr(n){return function(t){return kt(t,n)}}function er(n,t,r,e){var u=e?g:v,i=-1,o=t.length,f=n;for(n===t&&(t=Ur(t)),
+r&&(f=c(n,k(r)));++i<o;)for(var a=0,l=t[i],l=r?r(l):l;-1<(a=u(f,l,a,e));)f!==n&&xi.call(f,a,1),xi.call(n,a,1);return n}function ur(n,t){for(var r=n?t.length:0,e=r-1;r--;){var u=t[r];if(r==e||u!==i){var i=u;Se(u)?xi.call(n,u,1):xr(n,u)}}}function ir(n,t){return n+Ii(Ti()*(t-n+1))}function or(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=Ii(t/2))&&(n+=n);while(t);return r}function fr(n,t){return xo(Be(n,t,$u),n+"")}function cr(n){return Qn(Uu(n))}function ar(n,t){var r=Uu(n);
+return De(r,pt(t,0,r.length))}function lr(n,t,r,e){if(!du(n))return n;t=Sr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=Me(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):T;a===T&&(a=du(l)?l:Se(t[u+1])?[]:{})}ot(f,c,a),f=f[c]}return n}function sr(n){return De(Uu(n))}function hr(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Ku(u);++e<u;)r[e]=n[e+t];return r}function pr(n,t){var r;return uo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}
+function _r(n,t,r){var e=0,u=null==n?e:n.length;if(typeof t=="number"&&t===t&&2147483647>=u){for(;e<u;){var i=e+u>>>1,o=n[i];null!==o&&!wu(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return vr(n,t,$u,r)}function vr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=wu(t),a=t===T;u<i;){var l=Ii((u+i)/2),s=r(n[l]),h=s!==T,p=null===s,_=s===s,v=wu(s);(o?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?s<=t:s<t)?u=l+1:i=l}return Ci(i,4294967294)}function gr(n,t){for(var r=-1,e=n.length,u=0,i=[];++r<e;){
+var o=n[r],f=t?t(o):o;if(!r||!lu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function dr(n){return typeof n=="number"?n:wu(n)?F:+n}function yr(n){if(typeof n=="string")return n;if(ff(n))return c(n,yr)+"";if(wu(n))return ro?ro.call(n):"";var t=n+"";return"0"==t&&1/n==-$?"-0":t}function br(n,t,r){var e=-1,u=o,i=n.length,c=true,a=[],l=a;if(r)c=false,u=f;else if(200<=i){if(u=t?null:so(n))return U(u);c=false,u=O,l=new Nn}else l=t?[]:a;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(c&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;
+t&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function xr(n,t){return t=Sr(t,n),n=2>t.length?n:kt(n,hr(t,0,-1)),null==n||delete n[Me(Ve(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?hr(n,e?0:i,e?i+1:u):hr(n,e?i+1:0,e?u:i)}function wr(n,t){var r=n;return r instanceof Un&&(r=r.value()),l(t,function(n,t){return t.func.apply(t.thisArg,a([n],t.args))},r)}function mr(n,t,r){var e=n.length;if(2>e)return e?br(n[0]):[];for(var u=-1,i=Ku(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=yt(i[u]||o,n[f],t,r));
+return br(wt(i,1),t,r)}function Ar(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:T);return o}function Er(n){return hu(n)?n:[]}function kr(n){return typeof n=="function"?n:$u}function Sr(n,t){return ff(n)?n:Ie(n,t)?[n]:jo(Iu(n))}function Or(n,t,r){var e=n.length;return r=r===T?e:r,!t&&r>=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=gi?gi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new vi(t).set(new vi(n)),
+t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=wu(n),o=t!==T,f=null===t,c=t===t,a=wu(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&n<t||a&&r&&u&&!e&&!i||f&&r&&u||!o&&u||!c)return-1}return 0}function Br(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Ui(i-o,0),l=Ku(c+a);for(e=!e;++f<c;)l[f]=t[f];for(;++u<o;)(e||u<i)&&(l[r[u]]=n[u]);for(;a--;)l[f++]=n[u++];
+return l}function Lr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Ui(i-f,0),s=Ku(l+a);for(e=!e;++u<l;)s[u]=n[u];for(l=u;++c<a;)s[l+c]=t[c];for(;++o<f;)(e||u<i)&&(s[l+r[o]]=n[u++]);return s}function Ur(n,t){var r=-1,e=n.length;for(t||(t=Ku(e));++r<e;)t[r]=n[r];return t}function Cr(n,t,r,e){var u=!r;r||(r={});for(var i=-1,o=t.length;++i<o;){var f=t[i],c=e?e(r[f],n[f],f,r,n):T;c===T&&(c=n[f]),u?st(r,f,c):ot(r,f,c)}return r}function Dr(n,t){return Cr(n,po(n),t)}function Mr(n,t){return Cr(n,_o(n),t);
+}function Tr(n,r){return function(e,u){var i=ff(e)?t:ct,o=r?r():{};return i(e,n,ye(u,2),o)}}function $r(n){return fr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:T,o=2<u?r[2]:T,i=3<n.length&&typeof i=="function"?(u--,i):T;for(o&&Oe(r[0],r[1],o)&&(i=3>u?T:i,u=1),t=Qu(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Fr(n,t){return function(r,e){if(null==r)return r;if(!su(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=Qu(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Nr(n){return function(t,r,e){
+var u=-1,i=Qu(t);e=e(t);for(var o=e.length;o--;){var f=e[n?o:++u];if(false===r(i[f],f,i))break}return t}}function Pr(n,t,r){function e(){return(this&&this!==$n&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Vr(n);return e}function Zr(n){return function(t){t=Iu(t);var r=Rn.test(t)?M(t):T,e=r?r[0]:t.charAt(0);return t=r?Or(r,1).join(""):t.slice(1),e[n]()+t}}function qr(n){return function(t){return l(Mu(Du(t).replace(kn,"")),n,"")}}function Vr(n){return function(){var t=arguments;switch(t.length){
+case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4]);case 6:return new n(t[0],t[1],t[2],t[3],t[4],t[5]);case 7:return new n(t[0],t[1],t[2],t[3],t[4],t[5],t[6])}var r=eo(n.prototype),t=n.apply(r,t);return du(t)?t:r}}function Kr(t,r,e){function u(){for(var o=arguments.length,f=Ku(o),c=o,a=de(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:L(f,a),
+o-=c.length,o<e?ue(t,r,Jr,u.placeholder,T,f,c,T,T,e-o):n(this&&this!==$n&&this instanceof u?i:t,this,f)}var i=Vr(t);return u}function Gr(n){return function(t,r,e){var u=Qu(t);if(!su(t)){var i=ye(r,3);t=Wu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:T}}function Hr(n){return pe(function(t){var r=t.length,e=r,u=On.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ti("Expected a function");if(u&&!o&&"wrapper"==ge(i))var o=new On([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=ge(i),f="wrapper"==u?ho(i):T,o=f&&Re(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[ge(f[0])].apply(o,f[3]):1==i.length&&Re(i)?o[u]():o.thru(i);
+return function(){var n=arguments,e=n[0];if(o&&1==n.length&&ff(e))return o.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++u<r;)n=t[u].call(this,n);return n}})}function Jr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Ku(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=de(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Br(y,e,u,_)),i&&(y=Lr(y,i,o,_)),d-=x,_&&d<a)return j=L(y,j),ue(n,t,Jr,l.placeholder,r,y,j,f,c,a-d);if(j=h?r:this,b=p?j[n]:n,d=y.length,f){x=y.length;for(var w=Ci(f.length,x),m=Ur(y);w--;){
+var A=f[w];y[w]=Se(A,x)?m[A]:T}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==$n&&this instanceof l&&(b=g||Vr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?T:Vr(n);return l}function Yr(n,t){return function(r,e){return Bt(r,n,t(e))}}function Qr(n,t){return function(r,e){var u;if(r===T&&e===T)return t;if(r!==T&&(u=r),e!==T){if(u===T)return e;typeof r=="string"||typeof e=="string"?(r=yr(r),e=yr(e)):(r=dr(r),e=dr(e)),u=n(r,e)}return u}}function Xr(t){return pe(function(r){
+return r=c(r,k(ye())),fr(function(e){var u=this;return t(r,function(t){return n(t,u,e)})})})}function ne(n,t){t=t===T?" ":yr(t);var r=t.length;return 2>r?r?or(t,n):t:(r=or(t,Oi(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Ku(l+c),h=this&&this!==$n&&this instanceof i?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++r];return n(h,o?e:this,s)}var o=1&r,f=Vr(t);return i}function re(n){return function(t,r,e){
+e&&typeof e!="number"&&Oe(t,r,e)&&(r=e=T),t=Au(t),r===T?(r=t,t=0):r=Au(r),e=e===T?t<r?1:-1:Au(e);var u=-1;r=Ui(Oi((r-t)/(e||1)),0);for(var i=Ku(r);r--;)i[n?r:++u]=t,t+=e;return i}}function ee(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Su(t),r=Su(r)),n(t,r)}}function ue(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:T;o=l?T:o;var h=l?i:T;return i=l?T:i,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),u=[n,t,u,h,s,i,o,f,c,a],r=r.apply(T,u),Re(n)&&yo(r,u),r.placeholder=e,Ue(r,n,t)}function ie(n){
+var t=Yu[n];return function(n,r){if(n=Su(n),(r=null==r?0:Ci(Eu(r),292))&&Wi(n)){var e=(Iu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Iu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function oe(n){return function(t){var r=vo(t);return"[object Map]"==r?W(t):"[object Set]"==r?C(t):E(t,n(t))}}function fe(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ti("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=T),o=o===T?o:Ui(Eu(o),0),f=f===T?f:Eu(f),a-=u?u.length:0,
+64&t){var l=e,s=u;e=u=T}var h=c?T:ho(n);return i=[n,t,r,e,u,l,s,i,o,f],h&&(r=i[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&i[7].length<=h[8]||384==n&&h[7].length<=h[8]&&8==r,131>t||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ci(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],
+t=i[1],r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Ui(i[9]-a,0),!f&&24&t&&(t&=-25),Ue((h?co:yo)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||lu(n,ei[r])&&!oi.call(e,r)?t:n}function ae(n,t,r,e,u,i){return du(n)&&du(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return xu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;
var c=-1,a=true,l=2&r?new Nn:T;for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],p=t[c];if(e)var _=o?e(p,s,c,t,n,i):e(s,p,c,n,t,i);if(_!==T){if(_)continue;a=false;break}if(l){if(!h(t,function(n,t){if(!O(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==p&&!u(s,p,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function he(n,t,r,e,u,i,o){switch(r){case"[object DataView]":if(n.byteLength!=t.byteLength||n.byteOffset!=t.byteOffset)break;n=n.buffer,t=t.buffer;case"[object ArrayBuffer]":
-if(n.byteLength!=t.byteLength||!i(new vi(n),new vi(t)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return lu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=L),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(to)return to.call(n)==to.call(t)}
-return false}function pe(n){return xo(Ue(n,T,Ze),n+"")}function _e(n){return St(n,Wu,po)}function ve(n){return St(n,Uu,_o)}function ge(n){for(var t=n.name+"",r=Gi[t],e=oi.call(Gi,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(oi.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||Fu,n=n===Fu?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
+if(n.byteLength!=t.byteLength||!i(new vi(n),new vi(t)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return lu(+n,+t);case"[object Error]":return n.name==t.name&&n.message==t.message;case"[object RegExp]":case"[object String]":return n==t+"";case"[object Map]":var f=W;case"[object Set]":if(f||(f=U),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=se(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(to)return to.call(n)==to.call(t)}
+return false}function pe(n){return xo(Be(n,T,Ze),n+"")}function _e(n){return St(n,Wu,po)}function ve(n){return St(n,Bu,_o)}function ge(n){for(var t=n.name+"",r=Gi[t],e=oi.call(Gi,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function de(n){return(oi.call(An,"placeholder")?An:n).placeholder}function ye(){var n=An.iteratee||Fu,n=n===Fu?qt:n;return arguments.length?n(arguments[0],arguments[1]):n}function be(n,t){var r=n.__data__,e=typeof t;return("string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t)?r[typeof t=="string"?"string":"hash"]:r.map;
}function xe(n){for(var t=Wu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!du(u)]}return t}function je(n,t){var r=null==n?T:n[t];return Ft(r)?r:T}function we(n,t,r){t=Sr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=Me(t[e]);if(!(i=null!=n&&r(n,o)))break;n=n[o]}return i||++e!=u?i:(u=null==n?0:n.length,!!u&&gu(u)&&Se(o,u)&&(ff(n)||of(n)))}function me(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&oi.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Ae(n){
-return typeof n.constructor!="function"||ze(n)?{}:eo(di(n))}function ke(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
-case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return to?Qu(to.call(n)):{}}}function Ee(n){return ff(n)||of(n)||!!(ji&&n&&n[ji])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
-}function Oe(n,t,r){if(!du(r))return false;var e=typeof t;return!!("number"==e?su(r)&&Se(t,r.length):"string"==e&&t in r)&&lu(r[t],n)}function Ie(n,t){if(ff(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!wu(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Qu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Ln.prototype&&(n===r||(t=ho(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ei)}function We(n,t){
-return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Qu(r)))}}function Ue(t,r,e){return r=Li(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Li(u.length-r,0),f=Ku(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Ku(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Be(n,t){if("__proto__"!=t)return n[t]}function Le(n,t,r){var e=t+"";t=xo;var u,i=$e;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),
-t(n,e)}function Ce(n){var t=0,r=0;return function(){var e=Di(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function De(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function Me(n){if(typeof n=="string"||wu(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Te(n){if(null!=n){try{return ii.call(n)}catch(n){}return n+""}return""}function $e(n,t){return r(N,function(r){var e="_."+r[0];
-t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function Fe(n){if(n instanceof Ln)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Lr(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ne(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:ku(r),0>r&&(r=Li(e+r,0)),_(n,ye(t,3),r)):-1}function Pe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=ku(r),u=0>r?Li(e+u,0):Ci(u,e-1)),_(n,ye(t,3),u,true)}function Ze(n){return(null==n?0:n.length)?wt(n,1):[];
-}function qe(n){return n&&n.length?n[0]:T}function Ve(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ke(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ge(n){return null==n?n:$i.call(n)}function He(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(hu(n))return t=Li(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function Je(t,r){if(!t||!t.length)return[];var e=He(t);return null==r?e:c(e,function(t){return n(r,T,t)})}function Ye(n){return n=An(n),n.__chain__=true,n;
-}function Qe(n,t){return t(n)}function Xe(){return this}function nu(n,t){return(ff(n)?r:uo)(n,ye(t,3))}function tu(n,t){return(ff(n)?e:io)(n,ye(t,3))}function ru(n,t){return(ff(n)?c:Gt)(n,ye(t,3))}function eu(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function uu(n,t){var r;if(typeof t!="function")throw new ti("Expected a function");return n=ku(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),r}}function iu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=iu.placeholder,
-n}function ou(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=ou.placeholder,n}function fu(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Go();if(u(n))return o(n);var r,e=bo;r=n-_,n=t-(n-p),r=g?Ci(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Go(),r=u(n);if(c=arguments,a=this,p=n,r){if(h===T)return _=n=p,h=bo(i,t),v?e(n):s;if(g)return h=bo(i,t),e(p)}return h===T&&(h=bo(i,t)),
-s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ti("Expected a function");return t=Su(t)||0,du(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Li(Su(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&lo(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Go())},f}function cu(n,t){if(typeof n!="function"||null!=t&&typeof t!="function")throw new ti("Expected a function");var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),
-r.cache=i.set(u,e)||i,e)};return r.cache=new(cu.Cache||Fn),r}function au(n){if(typeof n!="function")throw new ti("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function lu(n,t){return n===t||n!==n&&t!==t}function su(n){return null!=n&&gu(n.length)&&!_u(n)}function hu(n){return yu(n)&&su(n)}function pu(n){if(!yu(n))return false;
-var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!xu(n)}function _u(n){return!!du(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function vu(n){return typeof n=="number"&&n==ku(n)}function gu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n}function du(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function yu(n){return null!=n&&typeof n=="object";
-}function bu(n){return typeof n=="number"||yu(n)&&"[object Number]"==Ot(n)}function xu(n){return!(!yu(n)||"[object Object]"!=Ot(n))&&(n=di(n),null===n||(n=oi.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ii.call(n)==li))}function ju(n){return typeof n=="string"||!ff(n)&&yu(n)&&"[object String]"==Ot(n)}function wu(n){return typeof n=="symbol"||yu(n)&&"[object Symbol]"==Ot(n)}function mu(n){if(!n)return[];if(su(n))return ju(n)?M(n):Lr(n);if(wi&&n[wi]){n=n[wi]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);
-return r}return t=vo(n),("[object Map]"==t?W:"[object Set]"==t?L:Lu)(n)}function Au(n){return n?(n=Su(n),n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function ku(n){n=Au(n);var t=n%1;return n===n?t?n-t:n:0}function Eu(n){return n?pt(ku(n),0,4294967295):0}function Su(n){if(typeof n=="number")return n;if(wu(n))return F;if(du(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=du(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n;
-}function Ou(n){return Cr(n,Uu(n))}function Iu(n){return null==n?"":yr(n)}function Ru(n,t,r){return n=null==n?T:Et(n,t),n===T?r:n}function zu(n,t){return null!=n&&we(n,t,zt)}function Wu(n){return su(n)?qn(n):Vt(n)}function Uu(n){if(su(n))n=qn(n,true);else if(du(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&oi.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in Qu(n))t.push(r);n=t}return n}function Bu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){
-return t(n,r[0])})}function Lu(n){return null==n?[]:S(n,Wu(n))}function Cu(n){return $f(Iu(n).toLowerCase())}function Du(n){return(n=Iu(n))&&n.replace(xn,Xn).replace(Sn,"")}function Mu(n,t,r){return n=Iu(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Tu(n){return function(){return n}}function $u(n){return n}function Fu(n){return qt(typeof n=="function"?n:_t(n,1))}function Nu(n,t,e){var u=Wu(t),i=kt(t,u);null!=e||du(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=kt(t,Wu(t)));
-var o=!(du(e)&&"chain"in e&&!e.chain),f=_u(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Lr(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Pu(){}function Zu(n){return Ie(n)?b(Me(n)):rr(n)}function qu(){return[]}function Vu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Ku=mn.Array,Gu=mn.Date,Hu=mn.Error,Ju=mn.Function,Yu=mn.Math,Qu=mn.Object,Xu=mn.RegExp,ni=mn.String,ti=mn.TypeError,ri=Ku.prototype,ei=Qu.prototype,ui=mn["__core-js_shared__"],ii=Ju.prototype.toString,oi=ei.hasOwnProperty,fi=0,ci=function(){
-var n=/[^.]+$/.exec(ui&&ui.keys&&ui.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ai=ei.toString,li=ii.call(Qu),si=$n._,hi=Xu("^"+ii.call(oi).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),pi=Pn?mn.Buffer:T,_i=mn.Symbol,vi=mn.Uint8Array,gi=pi?pi.allocUnsafe:T,di=U(Qu.getPrototypeOf,Qu),yi=Qu.create,bi=ei.propertyIsEnumerable,xi=ri.splice,ji=_i?_i.isConcatSpreadable:T,wi=_i?_i.iterator:T,mi=_i?_i.toStringTag:T,Ai=function(){try{var n=je(Qu,"defineProperty");
-return n({},"",{}),n}catch(n){}}(),ki=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,Ei=Gu&&Gu.now!==$n.Date.now&&Gu.now,Si=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Oi=Yu.ceil,Ii=Yu.floor,Ri=Qu.getOwnPropertySymbols,zi=pi?pi.isBuffer:T,Wi=mn.isFinite,Ui=ri.join,Bi=U(Qu.keys,Qu),Li=Yu.max,Ci=Yu.min,Di=Gu.now,Mi=mn.parseInt,Ti=Yu.random,$i=ri.reverse,Fi=je(mn,"DataView"),Ni=je(mn,"Map"),Pi=je(mn,"Promise"),Zi=je(mn,"Set"),qi=je(mn,"WeakMap"),Vi=je(Qu,"create"),Ki=qi&&new qi,Gi={},Hi=Te(Fi),Ji=Te(Ni),Yi=Te(Pi),Qi=Te(Zi),Xi=Te(qi),no=_i?_i.prototype:T,to=no?no.valueOf:T,ro=no?no.toString:T,eo=function(){
-function n(){}return function(t){return du(t)?yi?yi(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=kn.prototype,An.prototype.constructor=An,On.prototype=eo(kn.prototype),On.prototype.constructor=On,Ln.prototype=eo(kn.prototype),Ln.prototype.constructor=Ln,Mn.prototype.clear=function(){this.__data__=Vi?Vi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
+return typeof n.constructor!="function"||ze(n)?{}:eo(di(n))}function Ee(n,t,r){var e=n.constructor;switch(t){case"[object ArrayBuffer]":return Rr(n);case"[object Boolean]":case"[object Date]":return new e(+n);case"[object DataView]":return t=r?Rr(n.buffer):n.buffer,new n.constructor(t,n.byteOffset,n.byteLength);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":
+case"[object Uint16Array]":case"[object Uint32Array]":return zr(n,r);case"[object Map]":return new e;case"[object Number]":case"[object String]":return new e(n);case"[object RegExp]":return t=new n.constructor(n.source,_n.exec(n)),t.lastIndex=n.lastIndex,t;case"[object Set]":return new e;case"[object Symbol]":return to?Qu(to.call(n)):{}}}function ke(n){return ff(n)||of(n)||!!(ji&&n&&n[ji])}function Se(n,t){var r=typeof n;return t=null==t?9007199254740991:t,!!t&&("number"==r||"symbol"!=r&&bn.test(n))&&-1<n&&0==n%1&&n<t;
+}function Oe(n,t,r){if(!du(r))return false;var e=typeof t;return!!("number"==e?su(r)&&Se(t,r.length):"string"==e&&t in r)&&lu(r[t],n)}function Ie(n,t){if(ff(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!wu(n))||(nn.test(n)||!X.test(n)||null!=t&&n in Qu(t))}function Re(n){var t=ge(n),r=An[t];return typeof r=="function"&&t in Un.prototype&&(n===r||(t=ho(r),!!t&&n===t[0]))}function ze(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||ei)}function We(n,t){
+return function(r){return null!=r&&(r[n]===t&&(t!==T||n in Qu(r)))}}function Be(t,r,e){return r=Ui(r===T?t.length-1:r,0),function(){for(var u=arguments,i=-1,o=Ui(u.length-r,0),f=Ku(o);++i<o;)f[i]=u[r+i];for(i=-1,o=Ku(r+1);++i<r;)o[i]=u[i];return o[r]=e(f),n(t,this,o)}}function Le(n,t){if(("constructor"!==t||"function"!=typeof n[t])&&"__proto__"!=t)return n[t]}function Ue(n,t,r){var e=t+"";t=xo;var u,i=$e;return u=(u=e.match(an))?u[1].split(ln):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],
+r=r.join(2<i?", ":" "),e=e.replace(cn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Ce(n){var t=0,r=0;return function(){var e=Di(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(T,arguments)}}function De(n,t){var r=-1,e=n.length,u=e-1;for(t=t===T?e:t;++r<t;){var e=ir(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function Me(n){if(typeof n=="string"||wu(n))return n;var t=n+"";return"0"==t&&1/n==-$?"-0":t}function Te(n){if(null!=n){try{return ii.call(n)}catch(n){}
+return n+""}return""}function $e(n,t){return r(N,function(r){var e="_."+r[0];t&r[1]&&!o(n,e)&&n.push(e)}),n.sort()}function Fe(n){if(n instanceof Un)return n.clone();var t=new On(n.__wrapped__,n.__chain__);return t.__actions__=Ur(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ne(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),_(n,ye(t,3),r)):-1}function Pe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Eu(r),u=0>r?Ui(e+u,0):Ci(u,e-1)),
+_(n,ye(t,3),u,true)}function Ze(n){return(null==n?0:n.length)?wt(n,1):[]}function qe(n){return n&&n.length?n[0]:T}function Ve(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ke(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ge(n){return null==n?n:$i.call(n)}function He(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(hu(n))return t=Ui(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function Je(t,r){if(!t||!t.length)return[];var e=He(t);return null==r?e:c(e,function(t){
+return n(r,T,t)})}function Ye(n){return n=An(n),n.__chain__=true,n}function Qe(n,t){return t(n)}function Xe(){return this}function nu(n,t){return(ff(n)?r:uo)(n,ye(t,3))}function tu(n,t){return(ff(n)?e:io)(n,ye(t,3))}function ru(n,t){return(ff(n)?c:Gt)(n,ye(t,3))}function eu(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function uu(n,t){var r;if(typeof t!="function")throw new ti("Expected a function");return n=Eu(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),
+r}}function iu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=ou.placeholder,n}function fu(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Go();if(u(n))return o(n);var r,e=bo;r=n-_,n=t-(n-p),r=g?Ci(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Go(),r=u(n);if(c=arguments,
+a=this,p=n,r){if(h===T)return _=n=p,h=bo(i,t),v?e(n):s;if(g)return lo(h),h=bo(i,t),e(p)}return h===T&&(h=bo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ti("Expected a function");return t=Su(t)||0,du(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Ui(Su(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&lo(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Go())},f}function cu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;
+return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ti("Expected a function");return r.cache=new(cu.Cache||Fn),r}function au(n){if(typeof n!="function")throw new ti("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function lu(n,t){return n===t||n!==n&&t!==t;
+}function su(n){return null!=n&&gu(n.length)&&!_u(n)}function hu(n){return yu(n)&&su(n)}function pu(n){if(!yu(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!xu(n)}function _u(n){return!!du(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function vu(n){return typeof n=="number"&&n==Eu(n)}function gu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n;
+}function du(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function yu(n){return null!=n&&typeof n=="object"}function bu(n){return typeof n=="number"||yu(n)&&"[object Number]"==Ot(n)}function xu(n){return!(!yu(n)||"[object Object]"!=Ot(n))&&(n=di(n),null===n||(n=oi.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ii.call(n)==li))}function ju(n){return typeof n=="string"||!ff(n)&&yu(n)&&"[object String]"==Ot(n)}function wu(n){return typeof n=="symbol"||yu(n)&&"[object Symbol]"==Ot(n);
+}function mu(n){if(!n)return[];if(su(n))return ju(n)?M(n):Ur(n);if(wi&&n[wi]){n=n[wi]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=vo(n),("[object Map]"==t?W:"[object Set]"==t?U:Uu)(n)}function Au(n){return n?(n=Su(n),n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Eu(n){n=Au(n);var t=n%1;return n===n?t?n-t:n:0}function ku(n){return n?pt(Eu(n),0,4294967295):0}function Su(n){if(typeof n=="number")return n;if(wu(n))return F;if(du(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,
+n=du(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Ou(n){return Cr(n,Bu(n))}function Iu(n){return null==n?"":yr(n)}function Ru(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function zu(n,t){return null!=n&&we(n,t,zt)}function Wu(n){return su(n)?qn(n):Vt(n)}function Bu(n){if(su(n))n=qn(n,true);else if(du(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&oi.call(n,t))&&e.push(t);n=e}else{if(t=[],
+null!=n)for(r in Qu(n))t.push(r);n=t}return n}function Lu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Uu(n){return null==n?[]:S(n,Wu(n))}function Cu(n){return $f(Iu(n).toLowerCase())}function Du(n){return(n=Iu(n))&&n.replace(xn,Xn).replace(Sn,"")}function Mu(n,t,r){return n=Iu(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Tu(n){return function(){return n}}function $u(n){return n;
+}function Fu(n){return qt(typeof n=="function"?n:_t(n,1))}function Nu(n,t,e){var u=Wu(t),i=Et(t,u);null!=e||du(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,Wu(t)));var o=!(du(e)&&"chain"in e&&!e.chain),f=_u(n);return r(i,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Pu(){}
+function Zu(n){return Ie(n)?b(Me(n)):rr(n)}function qu(){return[]}function Vu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Ku=mn.Array,Gu=mn.Date,Hu=mn.Error,Ju=mn.Function,Yu=mn.Math,Qu=mn.Object,Xu=mn.RegExp,ni=mn.String,ti=mn.TypeError,ri=Ku.prototype,ei=Qu.prototype,ui=mn["__core-js_shared__"],ii=Ju.prototype.toString,oi=ei.hasOwnProperty,fi=0,ci=function(){var n=/[^.]+$/.exec(ui&&ui.keys&&ui.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ai=ei.toString,li=ii.call(Qu),si=$n._,hi=Xu("^"+ii.call(oi).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),pi=Pn?mn.Buffer:T,_i=mn.Symbol,vi=mn.Uint8Array,gi=pi?pi.g:T,di=B(Qu.getPrototypeOf,Qu),yi=Qu.create,bi=ei.propertyIsEnumerable,xi=ri.splice,ji=_i?_i.isConcatSpreadable:T,wi=_i?_i.iterator:T,mi=_i?_i.toStringTag:T,Ai=function(){
+try{var n=je(Qu,"defineProperty");return n({},"",{}),n}catch(n){}}(),Ei=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,ki=Gu&&Gu.now!==$n.Date.now&&Gu.now,Si=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Oi=Yu.ceil,Ii=Yu.floor,Ri=Qu.getOwnPropertySymbols,zi=pi?pi.isBuffer:T,Wi=mn.isFinite,Bi=ri.join,Li=B(Qu.keys,Qu),Ui=Yu.max,Ci=Yu.min,Di=Gu.now,Mi=mn.parseInt,Ti=Yu.random,$i=ri.reverse,Fi=je(mn,"DataView"),Ni=je(mn,"Map"),Pi=je(mn,"Promise"),Zi=je(mn,"Set"),qi=je(mn,"WeakMap"),Vi=je(Qu,"create"),Ki=qi&&new qi,Gi={},Hi=Te(Fi),Ji=Te(Ni),Yi=Te(Pi),Qi=Te(Zi),Xi=Te(qi),no=_i?_i.prototype:T,to=no?no.valueOf:T,ro=no?no.toString:T,eo=function(){
+function n(){}return function(t){return du(t)?yi?yi(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=eo(En.prototype),On.prototype.constructor=On,Un.prototype=eo(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=Vi?Vi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return Vi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):oi.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return Vi?t[n]!==T:oi.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Vi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():xi.call(t,n,1),
--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1<ft(this.__data__,n)},Tn.prototype.set=function(n,t){var r=this.__data__,e=ft(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Ni||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n);
},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){
-return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Ni||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var uo=Fr(mt),io=Fr(At,true),oo=Nr(),fo=Nr(true),co=Ki?function(n,t){return Ki.set(n,t),n}:$u,ao=Ai?function(n,t){return Ai(n,"toString",{configurable:true,enumerable:false,value:Tu(t),writable:true})}:$u,lo=ki||function(n){
-return $n.clearTimeout(n)},so=Zi&&1/L(new Zi([,-0]))[1]==$?function(n){return new Zi(n)}:Pu,ho=Ki?function(n){return Ki.get(n)}:Pu,po=Ri?function(n){return null==n?[]:(n=Qu(n),i(Ri(n),function(t){return bi.call(n,t)}))}:qu,_o=Ri?function(n){for(var t=[];n;)a(t,po(n)),n=di(n);return t}:qu,vo=Ot;(Fi&&"[object DataView]"!=vo(new Fi(new ArrayBuffer(1)))||Ni&&"[object Map]"!=vo(new Ni)||Pi&&"[object Promise]"!=vo(Pi.resolve())||Zi&&"[object Set]"!=vo(new Zi)||qi&&"[object WeakMap]"!=vo(new qi))&&(vo=function(n){
+return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Ni||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var uo=Fr(mt),io=Fr(At,true),oo=Nr(),fo=Nr(true),co=Ki?function(n,t){return Ki.set(n,t),n}:$u,ao=Ai?function(n,t){return Ai(n,"toString",{configurable:true,enumerable:false,value:Tu(t),writable:true})}:$u,lo=Ei||function(n){
+return $n.clearTimeout(n)},so=Zi&&1/U(new Zi([,-0]))[1]==$?function(n){return new Zi(n)}:Pu,ho=Ki?function(n){return Ki.get(n)}:Pu,po=Ri?function(n){return null==n?[]:(n=Qu(n),i(Ri(n),function(t){return bi.call(n,t)}))}:qu,_o=Ri?function(n){for(var t=[];n;)a(t,po(n)),n=di(n);return t}:qu,vo=Ot;(Fi&&"[object DataView]"!=vo(new Fi(new ArrayBuffer(1)))||Ni&&"[object Map]"!=vo(new Ni)||Pi&&"[object Promise]"!=vo(Pi.resolve())||Zi&&"[object Set]"!=vo(new Zi)||qi&&"[object WeakMap]"!=vo(new qi))&&(vo=function(n){
var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Te(n):"")switch(n){case Hi:return"[object DataView]";case Ji:return"[object Map]";case Yi:return"[object Promise]";case Qi:return"[object Set]";case Xi:return"[object WeakMap]"}return t});var go=ui?_u:Vu,yo=Ce(co),bo=Si||function(n,t){return $n.setTimeout(n,t)},xo=Ce(ao),jo=function(n){n=cu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){
-t.push(e?u.replace(hn,"$1"):r||n)}),t}),wo=fr(function(n,t){return hu(n)?yt(n,wt(t,1,hu,true)):[]}),mo=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),ye(r,2)):[]}),Ao=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),T,r):[]}),ko=fr(function(n){var t=c(n,kr);return t.length&&t[0]===n[0]?Wt(t):[]}),Eo=fr(function(n){var t=Ve(n),r=c(n,kr);return t===Ve(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),So=fr(function(n){var t=Ve(n),r=c(n,kr);return(t=typeof t=="function"?t:T)&&r.pop(),
-r.length&&r[0]===n[0]?Wt(r,T,t):[]}),Oo=fr(Ke),Io=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Ro=fr(function(n){return br(wt(n,1,hu,true))}),zo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),br(wt(n,1,hu,true),ye(t,2))}),Wo=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return br(wt(n,1,hu,true),T,t)}),Uo=fr(function(n,t){return hu(n)?yt(n,t):[]}),Bo=fr(function(n){return mr(i(n,hu))}),Lo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),
-mr(i(n,hu),ye(t,2))}),Co=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return mr(i(n,hu),T,t)}),Do=fr(He),Mo=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return Je(n,t)}),To=pe(function(n){var t=n.length,r=t?n[0]:0,e=this.__wrapped__,u=function(t){return ht(t,n)};return!(1<t||this.__actions__.length)&&e instanceof Ln&&Se(r)?(e=e.slice(r,+r+(t?1:0)),e.__actions__.push({func:Qe,args:[u],thisArg:T}),new On(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(T),
-n})):this.thru(u)}),$o=Tr(function(n,t,r){oi.call(n,r)?++n[r]:st(n,r,1)}),Fo=Gr(Ne),No=Gr(Pe),Po=Tr(function(n,t,r){oi.call(n,r)?n[r].push(t):st(n,r,[t])}),Zo=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=su(t)?Ku(t.length):[];return uo(t,function(t){o[++u]=i?n(r,t,e):Bt(t,r,e)}),o}),qo=Tr(function(n,t,r){st(n,r,t)}),Vo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ko=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
-Xt(n,wt(t,1),[])}),Go=Ei||function(){return $n.Date.now()},Ho=fr(function(n,t,r){var e=1;if(r.length)var u=B(r,de(Ho)),e=32|e;return fe(n,e,t,r,u)}),Jo=fr(function(n,t,r){var e=3;if(r.length)var u=B(r,de(Jo)),e=32|e;return fe(t,e,n,r,u)}),Yo=fr(function(n,t){return dt(n,1,t)}),Qo=fr(function(n,t,r){return dt(n,Su(t)||0,r)});cu.Cache=Fn;var Xo=fr(function(t,r){r=1==r.length&&ff(r[0])?c(r[0],E(ye())):c(wt(r,1),E(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ci(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
-return n(t,this,u)})}),nf=fr(function(n,t){return fe(n,32,T,t,B(t,de(nf)))}),tf=fr(function(n,t){return fe(n,64,T,t,B(t,de(tf)))}),rf=pe(function(n,t){return fe(n,256,T,T,T,t)}),ef=ee(It),uf=ee(function(n,t){return n>=t}),of=Lt(function(){return arguments}())?Lt:function(n){return yu(n)&&oi.call(n,"callee")&&!bi.call(n,"callee")},ff=Ku.isArray,cf=Vn?E(Vn):Ct,af=zi||Vu,lf=Kn?E(Kn):Dt,sf=Gn?E(Gn):Tt,hf=Hn?E(Hn):Nt,pf=Jn?E(Jn):Pt,_f=Yn?E(Yn):Zt,vf=ee(Kt),gf=ee(function(n,t){return n<=t}),df=$r(function(n,t){
-if(ze(t)||su(t))Cr(t,Wu(t),n);else for(var r in t)oi.call(t,r)&&ot(n,r,t[r])}),yf=$r(function(n,t){Cr(t,Uu(t),n)}),bf=$r(function(n,t,r,e){Cr(t,Uu(t),n,e)}),xf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),jf=pe(ht),wf=fr(function(n,t){n=Qu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Uu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||lu(a,ei[c])&&!oi.call(n,c))&&(n[c]=u[c])}return n}),mf=fr(function(t){return t.push(T,ae),n(Of,T,t)}),Af=Yr(function(n,t,r){
-null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),n[t]=r},Tu($u)),kf=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),oi.call(n,t)?n[t].push(r):n[t]=[r]},ye),Ef=fr(Bt),Sf=$r(function(n,t,r){Yt(n,t,r)}),Of=$r(function(n,t,r,e){Yt(n,t,r,e)}),If=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),Rf=pe(function(n,t){return null==n?{}:nr(n,t);
-}),zf=oe(Wu),Wf=oe(Uu),Uf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Cu(t):t)}),Bf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Lf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Cf=Zr("toLowerCase"),Df=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Mf=qr(function(n,t,r){return n+(r?" ":"")+$f(t)}),Tf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),$f=Zr("toUpperCase"),Ff=fr(function(t,r){try{return n(t,T,r)}catch(n){return pu(n)?n:new Hu(n)}}),Nf=pe(function(n,t){
-return r(t,function(t){t=Me(t),st(n,t,Ho(n[t],n))}),n}),Pf=Hr(),Zf=Hr(true),qf=fr(function(n,t){return function(r){return Bt(r,n,t)}}),Vf=fr(function(n,t){return function(r){return Bt(n,r,t)}}),Kf=Xr(c),Gf=Xr(u),Hf=Xr(h),Jf=re(),Yf=re(true),Qf=Qr(function(n,t){return n+t},0),Xf=ie("ceil"),nc=Qr(function(n,t){return n/t},1),tc=ie("floor"),rc=Qr(function(n,t){return n*t},1),ec=ie("round"),uc=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ti("Expected a function");
-return n=ku(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=eu,An.assign=df,An.assignIn=yf,An.assignInWith=bf,An.assignWith=xf,An.at=jf,An.before=uu,An.bind=Ho,An.bindAll=Nf,An.bindKey=Jo,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ff(n)?n:[n]},An.chain=Ye,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Li(ku(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Ku(Oi(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
-var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Ku(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(ff(r)?Lr(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ti("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Tu,
-An.countBy=$o,An.create=function(n,t){var r=eo(n);return null==t?r:at(r,t)},An.curry=iu,An.curryRight=ou,An.debounce=fu,An.defaults=wf,An.defaultsDeep=mf,An.defer=Yo,An.delay=Qo,An.difference=wo,An.differenceBy=mo,An.differenceWith=Ao,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:ku(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:ku(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
-},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=ku(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:ku(e),0>e&&(e+=u),e=r>e?0:Eu(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(ff(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(ru(n,t),1)},An.flatMapDeep=function(n,t){return wt(ru(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:ku(r),
-wt(ru(n,t),r)},An.flatten=Ze,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:ku(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Pf,An.flowRight=Zf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:kt(n,Wu(n))},An.functionsIn=function(n){return null==n?[]:kt(n,Uu(n))},An.groupBy=Po,An.initial=function(n){
-return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=ko,An.intersectionBy=Eo,An.intersectionWith=So,An.invert=Af,An.invertBy=kf,An.invokeMap=Zo,An.iteratee=Fu,An.keyBy=qo,An.keys=Wu,An.keysIn=Uu,An.map=ru,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=cu,
-An.merge=Sf,An.mergeWith=Of,An.method=qf,An.methodOf=Vf,An.mixin=Nu,An.negate=au,An.nthArg=function(n){return n=ku(n),fr(function(t){return Qt(t,n)})},An.omit=If,An.omitBy=function(n,t){return Bu(n,au(ye(t)))},An.once=function(n){return uu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(ff(t)||(t=null==t?[]:[t]),r=e?T:r,ff(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Kf,An.overArgs=Xo,An.overEvery=Gf,An.overSome=Hf,An.partial=nf,An.partialRight=tf,An.partition=Vo,An.pick=Rf,An.pickBy=Bu,An.property=Zu,
-An.propertyOf=function(n){return function(t){return null==n?T:Et(n,t)}},An.pull=Oo,An.pullAll=Ke,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Io,An.range=Jf,An.rangeRight=Yf,An.rearg=rf,An.reject=function(n,t){return(ff(n)?i:jt)(n,au(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
-u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ti("Expected a function");return t=t===T?t:ku(t),fr(n,t)},An.reverse=Ge,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:ku(t),(ff(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(ff(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
-r=e):(t=null==t?0:ku(t),r=r===T?e:ku(r)),hr(n,t,r)):[]},An.sortBy=Ko,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Iu(n))&&(typeof t=="string"||null!=t&&!hf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ti("Expected a function");return r=null==r?0:Li(ku(r),0),
-fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:ku(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:ku(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
-n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ti("Expected a function");return du(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),fu(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Qe,An.toArray=mu,An.toPairs=zf,An.toPairsIn=Wf,An.toPath=function(n){return ff(n)?c(n,Me):wu(n)?[n]:Lr(jo(Iu(n)))},An.toPlainObject=Ou,An.transform=function(n,t,e){var u=ff(n),i=u||af(n)||_f(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:du(n)&&_u(o)?eo(di(n)):{};
-}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return eu(n,1)},An.union=Ro,An.unionBy=zo,An.unionWith=Wo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=He,An.unzipWith=Je,An.update=function(n,t,r){return null!=n&&(r=Er(r),n=lr(n,t,r(Et(n,t)),void 0)),n},An.updateWith=function(n,t,r,e){
-return e=typeof e=="function"?e:T,null!=n&&(r=Er(r),n=lr(n,t,r(Et(n,t)),e)),n},An.values=Lu,An.valuesIn=function(n){return null==n?[]:S(n,Uu(n))},An.without=Uo,An.words=Mu,An.wrap=function(n,t){return nf(Er(t),n)},An.xor=Bo,An.xorBy=Lo,An.xorWith=Co,An.zip=Do,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Mo,An.entries=zf,An.entriesIn=Wf,An.extend=yf,An.extendWith=bf,Nu(An,An),An.add=Qf,An.attempt=Ff,An.camelCase=Uf,An.capitalize=Cu,
+t.push(e?u.replace(hn,"$1"):r||n)}),t}),wo=fr(function(n,t){return hu(n)?yt(n,wt(t,1,hu,true)):[]}),mo=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),ye(r,2)):[]}),Ao=fr(function(n,t){var r=Ve(t);return hu(r)&&(r=T),hu(n)?yt(n,wt(t,1,hu,true),T,r):[]}),Eo=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),ko=fr(function(n){var t=Ve(n),r=c(n,Er);return t===Ve(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),So=fr(function(n){var t=Ve(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(),
+r.length&&r[0]===n[0]?Wt(r,T,t):[]}),Oo=fr(Ke),Io=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Ro=fr(function(n){return br(wt(n,1,hu,true))}),zo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),br(wt(n,1,hu,true),ye(t,2))}),Wo=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return br(wt(n,1,hu,true),T,t)}),Bo=fr(function(n,t){return hu(n)?yt(n,t):[]}),Lo=fr(function(n){return mr(i(n,hu))}),Uo=fr(function(n){var t=Ve(n);return hu(t)&&(t=T),
+mr(i(n,hu),ye(t,2))}),Co=fr(function(n){var t=Ve(n),t=typeof t=="function"?t:T;return mr(i(n,hu),T,t)}),Do=fr(He),Mo=fr(function(n){var t=n.length,t=1<t?n[t-1]:T,t=typeof t=="function"?(n.pop(),t):T;return Je(n,t)}),To=pe(function(n){function t(t){return ht(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Un&&Se(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(T),
+n})):this.thru(t)}),$o=Tr(function(n,t,r){oi.call(n,r)?++n[r]:st(n,r,1)}),Fo=Gr(Ne),No=Gr(Pe),Po=Tr(function(n,t,r){oi.call(n,r)?n[r].push(t):st(n,r,[t])}),Zo=fr(function(t,r,e){var u=-1,i=typeof r=="function",o=su(t)?Ku(t.length):[];return uo(t,function(t){o[++u]=i?n(r,t,e):Lt(t,r,e)}),o}),qo=Tr(function(n,t,r){st(n,r,t)}),Vo=Tr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ko=fr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&Oe(n,t[0],t[1])?t=[]:2<r&&Oe(t[0],t[1],t[2])&&(t=[t[0]]),
+Xt(n,wt(t,1),[])}),Go=ki||function(){return $n.Date.now()},Ho=fr(function(n,t,r){var e=1;if(r.length)var u=L(r,de(Ho)),e=32|e;return fe(n,e,t,r,u)}),Jo=fr(function(n,t,r){var e=3;if(r.length)var u=L(r,de(Jo)),e=32|e;return fe(t,e,n,r,u)}),Yo=fr(function(n,t){return dt(n,1,t)}),Qo=fr(function(n,t,r){return dt(n,Su(t)||0,r)});cu.Cache=Fn;var Xo=fr(function(t,r){r=1==r.length&&ff(r[0])?c(r[0],k(ye())):c(wt(r,1),k(ye()));var e=r.length;return fr(function(u){for(var i=-1,o=Ci(u.length,e);++i<o;)u[i]=r[i].call(this,u[i]);
+return n(t,this,u)})}),nf=fr(function(n,t){return fe(n,32,T,t,L(t,de(nf)))}),tf=fr(function(n,t){return fe(n,64,T,t,L(t,de(tf)))}),rf=pe(function(n,t){return fe(n,256,T,T,T,t)}),ef=ee(It),uf=ee(function(n,t){return n>=t}),of=Ut(function(){return arguments}())?Ut:function(n){return yu(n)&&oi.call(n,"callee")&&!bi.call(n,"callee")},ff=Ku.isArray,cf=Vn?k(Vn):Ct,af=zi||Vu,lf=Kn?k(Kn):Dt,sf=Gn?k(Gn):Tt,hf=Hn?k(Hn):Nt,pf=Jn?k(Jn):Pt,_f=Yn?k(Yn):Zt,vf=ee(Kt),gf=ee(function(n,t){return n<=t}),df=$r(function(n,t){
+if(ze(t)||su(t))Cr(t,Wu(t),n);else for(var r in t)oi.call(t,r)&&ot(n,r,t[r])}),yf=$r(function(n,t){Cr(t,Bu(t),n)}),bf=$r(function(n,t,r,e){Cr(t,Bu(t),n,e)}),xf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),jf=pe(ht),wf=fr(function(n,t){n=Qu(n);var r=-1,e=t.length,u=2<e?t[2]:T;for(u&&Oe(t[0],t[1],u)&&(e=1);++r<e;)for(var u=t[r],i=Bu(u),o=-1,f=i.length;++o<f;){var c=i[o],a=n[c];(a===T||lu(a,ei[c])&&!oi.call(n,c))&&(n[c]=u[c])}return n}),mf=fr(function(t){return t.push(T,ae),n(Of,T,t)}),Af=Yr(function(n,t,r){
+null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),n[t]=r},Tu($u)),Ef=Yr(function(n,t,r){null!=t&&typeof t.toString!="function"&&(t=ai.call(t)),oi.call(n,t)?n[t].push(r):n[t]=[r]},ye),kf=fr(Lt),Sf=$r(function(n,t,r){Yt(n,t,r)}),Of=$r(function(n,t,r,e){Yt(n,t,r,e)}),If=pe(function(n,t){var r={};if(null==n)return r;var e=false;t=c(t,function(t){return t=Sr(t,n),e||(e=1<t.length),t}),Cr(n,ve(n),r),e&&(r=_t(r,7,le));for(var u=t.length;u--;)xr(r,t[u]);return r}),Rf=pe(function(n,t){return null==n?{}:nr(n,t);
+}),zf=oe(Wu),Wf=oe(Bu),Bf=qr(function(n,t,r){return t=t.toLowerCase(),n+(r?Cu(t):t)}),Lf=qr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Uf=qr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Cf=Zr("toLowerCase"),Df=qr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),Mf=qr(function(n,t,r){return n+(r?" ":"")+$f(t)}),Tf=qr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),$f=Zr("toUpperCase"),Ff=fr(function(t,r){try{return n(t,T,r)}catch(n){return pu(n)?n:new Hu(n)}}),Nf=pe(function(n,t){
+return r(t,function(t){t=Me(t),st(n,t,Ho(n[t],n))}),n}),Pf=Hr(),Zf=Hr(true),qf=fr(function(n,t){return function(r){return Lt(r,n,t)}}),Vf=fr(function(n,t){return function(r){return Lt(n,r,t)}}),Kf=Xr(c),Gf=Xr(u),Hf=Xr(h),Jf=re(),Yf=re(true),Qf=Qr(function(n,t){return n+t},0),Xf=ie("ceil"),nc=Qr(function(n,t){return n/t},1),tc=ie("floor"),rc=Qr(function(n,t){return n*t},1),ec=ie("round"),uc=Qr(function(n,t){return n-t},0);return An.after=function(n,t){if(typeof t!="function")throw new ti("Expected a function");
+return n=Eu(n),function(){if(1>--n)return t.apply(this,arguments)}},An.ary=eu,An.assign=df,An.assignIn=yf,An.assignInWith=bf,An.assignWith=xf,An.at=jf,An.before=uu,An.bind=Ho,An.bindAll=Nf,An.bindKey=Jo,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return ff(n)?n:[n]},An.chain=Ye,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Ui(Eu(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Ku(Oi(r/t));e<r;)i[u++]=hr(n,e,e+=t);return i},An.compact=function(n){for(var t=-1,r=null==n?0:n.length,e=0,u=[];++t<r;){
+var i=n[t];i&&(u[e++]=i)}return u},An.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Ku(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return a(ff(r)?Ur(r):[r],wt(t,1))},An.cond=function(t){var r=null==t?0:t.length,e=ye();return t=r?c(t,function(n){if("function"!=typeof n[1])throw new ti("Expected a function");return[e(n[0]),n[1]]}):[],fr(function(e){for(var u=-1;++u<r;){var i=t[u];if(n(i[0],this,e))return n(i[1],this,e)}})},An.conforms=function(n){return vt(_t(n,1))},An.constant=Tu,
+An.countBy=$o,An.create=function(n,t){var r=eo(n);return null==t?r:at(r,t)},An.curry=iu,An.curryRight=ou,An.debounce=fu,An.defaults=wf,An.defaultsDeep=mf,An.defer=Yo,An.delay=Qo,An.difference=wo,An.differenceBy=mo,An.differenceWith=Ao,An.drop=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),hr(n,0>t?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[];
+},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Eu(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Eu(e),0>e&&(e+=u),e=r>e?0:ku(e);r<e;)n[r++]=t;return n},An.filter=function(n,t){return(ff(n)?i:jt)(n,ye(t,3))},An.flatMap=function(n,t){return wt(ru(n,t),1)},An.flatMapDeep=function(n,t){return wt(ru(n,t),$)},An.flatMapDepth=function(n,t,r){return r=r===T?1:Eu(r),
+wt(ru(n,t),r)},An.flatten=Ze,An.flattenDeep=function(n){return(null==n?0:n.length)?wt(n,$):[]},An.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===T?1:Eu(t),wt(n,t)):[]},An.flip=function(n){return fe(n,512)},An.flow=Pf,An.flowRight=Zf,An.fromPairs=function(n){for(var t=-1,r=null==n?0:n.length,e={};++t<r;){var u=n[t];e[u[0]]=u[1]}return e},An.functions=function(n){return null==n?[]:Et(n,Wu(n))},An.functionsIn=function(n){return null==n?[]:Et(n,Bu(n))},An.groupBy=Po,An.initial=function(n){
+return(null==n?0:n.length)?hr(n,0,-1):[]},An.intersection=Eo,An.intersectionBy=ko,An.intersectionWith=So,An.invert=Af,An.invertBy=Ef,An.invokeMap=Zo,An.iteratee=Fu,An.keyBy=qo,An.keys=Wu,An.keysIn=Bu,An.map=ru,An.mapKeys=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,t(n,e,u),n)}),r},An.mapValues=function(n,t){var r={};return t=ye(t,3),mt(n,function(n,e,u){st(r,e,t(n,e,u))}),r},An.matches=function(n){return Ht(_t(n,1))},An.matchesProperty=function(n,t){return Jt(n,_t(t,1))},An.memoize=cu,
+An.merge=Sf,An.mergeWith=Of,An.method=qf,An.methodOf=Vf,An.mixin=Nu,An.negate=au,An.nthArg=function(n){return n=Eu(n),fr(function(t){return Qt(t,n)})},An.omit=If,An.omitBy=function(n,t){return Lu(n,au(ye(t)))},An.once=function(n){return uu(2,n)},An.orderBy=function(n,t,r,e){return null==n?[]:(ff(t)||(t=null==t?[]:[t]),r=e?T:r,ff(r)||(r=null==r?[]:[r]),Xt(n,t,r))},An.over=Kf,An.overArgs=Xo,An.overEvery=Gf,An.overSome=Hf,An.partial=nf,An.partialRight=tf,An.partition=Vo,An.pick=Rf,An.pickBy=Lu,An.property=Zu,
+An.propertyOf=function(n){return function(t){return null==n?T:kt(n,t)}},An.pull=Oo,An.pullAll=Ke,An.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,ye(r,2)):n},An.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?er(n,t,T,r):n},An.pullAt=Io,An.range=Jf,An.rangeRight=Yf,An.rearg=rf,An.reject=function(n,t){return(ff(n)?i:jt)(n,au(ye(t,3)))},An.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=ye(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),
+u.push(e))}return ur(n,u),r},An.rest=function(n,t){if(typeof n!="function")throw new ti("Expected a function");return t=t===T?t:Eu(t),fr(n,t)},An.reverse=Ge,An.sampleSize=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),(ff(n)?et:ar)(n,t)},An.set=function(n,t,r){return null==n?n:lr(n,t,r)},An.setWith=function(n,t,r,e){return e=typeof e=="function"?e:T,null==n?n:lr(n,t,r,e)},An.shuffle=function(n){return(ff(n)?ut:sr)(n)},An.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&Oe(n,t,r)?(t=0,
+r=e):(t=null==t?0:Eu(t),r=r===T?e:Eu(r)),hr(n,t,r)):[]},An.sortBy=Ko,An.sortedUniq=function(n){return n&&n.length?gr(n):[]},An.sortedUniqBy=function(n,t){return n&&n.length?gr(n,ye(t,2)):[]},An.split=function(n,t,r){return r&&typeof r!="number"&&Oe(n,t,r)&&(t=r=T),r=r===T?4294967295:r>>>0,r?(n=Iu(n))&&(typeof t=="string"||null!=t&&!hf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ti("Expected a function");return r=null==r?0:Ui(Eu(r),0),
+fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Eu(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Eu(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n),
+n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ti("Expected a function");return du(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),fu(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Qe,An.toArray=mu,An.toPairs=zf,An.toPairsIn=Wf,An.toPath=function(n){return ff(n)?c(n,Me):wu(n)?[n]:Ur(jo(Iu(n)))},An.toPlainObject=Ou,An.transform=function(n,t,e){var u=ff(n),i=u||af(n)||_f(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:du(n)&&_u(o)?eo(di(n)):{};
+}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return eu(n,1)},An.union=Ro,An.unionBy=zo,An.unionWith=Wo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=He,An.unzipWith=Je,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){
+return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Uu,An.valuesIn=function(n){return null==n?[]:S(n,Bu(n))},An.without=Bo,An.words=Mu,An.wrap=function(n,t){return nf(kr(t),n)},An.xor=Lo,An.xorBy=Uo,An.xorWith=Co,An.zip=Do,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Mo,An.entries=zf,An.entriesIn=Wf,An.extend=yf,An.extendWith=bf,Nu(An,An),An.add=Qf,An.attempt=Ff,An.camelCase=Bf,An.capitalize=Cu,
An.ceil=Xf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=Su(r),r=r===r?r:0),t!==T&&(t=Su(t),t=t===t?t:0),pt(Su(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,Wu(t))},An.deburr=Du,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=nc,An.endsWith=function(n,t,r){
-n=Iu(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(ku(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=lu,An.escape=function(n){return(n=Iu(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Iu(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=ff(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=Fo,An.findIndex=Ne,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=No,An.findLastIndex=Pe,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
-},An.floor=tc,An.forEach=nu,An.forEachRight=tu,An.forIn=function(n,t){return null==n?n:oo(n,ye(t,3),Uu)},An.forInRight=function(n,t){return null==n?n:fo(n,ye(t,3),Uu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Ru,An.gt=ef,An.gte=uf,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=zu,An.head=qe,An.identity=$u,An.includes=function(n,t,r,e){return n=su(n)?n:Lu(n),r=r&&!e?ku(r):0,e=n.length,0>r&&(r=Li(e+r,0)),ju(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
-},An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:ku(r),0>r&&(r=Li(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=Au(t),r===T?(r=t,t=0):r=Au(r),n=Su(n),n>=Ci(t,r)&&n<Li(t,r)},An.invoke=Ef,An.isArguments=of,An.isArray=ff,An.isArrayBuffer=cf,An.isArrayLike=su,An.isArrayLikeObject=hu,An.isBoolean=function(n){return true===n||false===n||yu(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=af,An.isDate=lf,An.isElement=function(n){return yu(n)&&1===n.nodeType&&!xu(n)},An.isEmpty=function(n){
+n=Iu(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Eu(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=lu,An.escape=function(n){return(n=Iu(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Iu(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=ff(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=Fo,An.findIndex=Ne,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=No,An.findLastIndex=Pe,An.findLastKey=function(n,t){return p(n,ye(t,3),At);
+},An.floor=tc,An.forEach=nu,An.forEachRight=tu,An.forIn=function(n,t){return null==n?n:oo(n,ye(t,3),Bu)},An.forInRight=function(n,t){return null==n?n:fo(n,ye(t,3),Bu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Ru,An.gt=ef,An.gte=uf,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=zu,An.head=qe,An.identity=$u,An.includes=function(n,t,r,e){return n=su(n)?n:Uu(n),r=r&&!e?Eu(r):0,e=n.length,0>r&&(r=Ui(e+r,0)),ju(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<v(n,t,r);
+},An.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Eu(r),0>r&&(r=Ui(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=Au(t),r===T?(r=t,t=0):r=Au(r),n=Su(n),n>=Ci(t,r)&&n<Ui(t,r)},An.invoke=kf,An.isArguments=of,An.isArray=ff,An.isArrayBuffer=cf,An.isArrayLike=su,An.isArrayLikeObject=hu,An.isBoolean=function(n){return true===n||false===n||yu(n)&&"[object Boolean]"==Ot(n)},An.isBuffer=af,An.isDate=lf,An.isElement=function(n){return yu(n)&&1===n.nodeType&&!xu(n)},An.isEmpty=function(n){
if(null==n)return true;if(su(n)&&(ff(n)||typeof n=="string"||typeof n.splice=="function"||af(n)||_f(n)||of(n)))return!n.length;var t=vo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(ze(n))return!Vt(n).length;for(var r in n)if(oi.call(n,r))return false;return true},An.isEqual=function(n,t){return Mt(n,t)},An.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:T)?r(n,t):T;return e===T?Mt(n,t,T,r):!!e},An.isError=pu,An.isFinite=function(n){return typeof n=="number"&&Wi(n)},An.isFunction=_u,
An.isInteger=vu,An.isLength=gu,An.isMap=sf,An.isMatch=function(n,t){return n===t||$t(n,t,xe(t))},An.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:T,$t(n,t,xe(t),r)},An.isNaN=function(n){return bu(n)&&n!=+n},An.isNative=function(n){if(go(n))throw new Hu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");return Ft(n)},An.isNil=function(n){return null==n},An.isNull=function(n){return null===n},An.isNumber=bu,An.isObject=du,An.isObjectLike=yu,An.isPlainObject=xu,An.isRegExp=hf,
-An.isSafeInteger=function(n){return vu(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=pf,An.isString=ju,An.isSymbol=wu,An.isTypedArray=_f,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return yu(n)&&"[object WeakMap]"==vo(n)},An.isWeakSet=function(n){return yu(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Ui.call(n,t)},An.kebabCase=Bf,An.last=Ve,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=ku(r),u=0>u?Li(e+u,0):Ci(u,e-1)),
-t===t)n:{for(r=u+1;r--;)if(n[r]===t){n=r;break n}n=r}else n=_(n,d,u,true);return n},An.lowerCase=Lf,An.lowerFirst=Cf,An.lt=vf,An.lte=gf,An.max=function(n){return n&&n.length?xt(n,$u,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,$u)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,$u,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=qu,An.stubFalse=Vu,An.stubObject=function(){
-return{}},An.stubString=function(){return""},An.stubTrue=function(){return true},An.multiply=rc,An.nth=function(n,t){return n&&n.length?Qt(n,ku(t)):T},An.noConflict=function(){return $n._===this&&($n._=si),this},An.noop=Pu,An.now=Go,An.pad=function(n,t,r){n=Iu(n);var e=(t=ku(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Ii(t),r)+n+ne(Oi(t),r))},An.padEnd=function(n,t,r){n=Iu(n);var e=(t=ku(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Iu(n);var e=(t=ku(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n;
-},An.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),Mi(Iu(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=Au(n),t===T?(t=n,n=0):t=Au(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Ti(),Ci(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=ff(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,uo)},An.reduceRight=function(n,t,r){
-var e=ff(n)?s:j,u=3>arguments.length;return e(n,ye(t,4),r,u,io)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:ku(t),or(Iu(n),t)},An.replace=function(){var n=arguments,t=Iu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[Me(t[e])];i===T&&(e=u,i=r),n=_u(i)?i.call(n):i}return n},An.round=ec,An.runInContext=x,An.sample=function(n){return(ff(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;
-if(su(n))return ju(n)?D(n):n.length;var t=vo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Df,An.some=function(n,t,r){var e=ff(n)?h:pr;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&lu(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){
-return vr(n,t,ye(r,2),true)},An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(lu(n[r],t))return r}return-1},An.startCase=Mf,An.startsWith=function(n,t,r){return n=Iu(n),r=null==r?0:pt(ku(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=uc,An.sum=function(n){return n&&n.length?m(n,$u):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Iu(n),t=bf({},t,e,ce),r=bf({},t.imports,e.imports,ce);
-var u,i,o=Wu(r),f=S(r,o),c=0;r=t.interpolate||jn;var a="__p+='";r=Xu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),
-a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Ff(function(){return Ju(o,l+"return "+a).apply(T,f)}),t.source=a,pu(t))throw t;return t},An.times=function(n,t){if(n=ku(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ci(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=Au,An.toInteger=ku,An.toLength=Eu,An.toLower=function(n){
-return Iu(n).toLowerCase()},An.toNumber=Su,An.toSafeInteger=function(n){return n?pt(ku(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Iu,An.toUpper=function(n){return Iu(n).toUpperCase()},An.trim=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){
-return(n=Iu(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(du(t))var u="separator"in t?t.separator:u,r="length"in t?ku(t.length):r,e="omission"in t?yr(t.omission):e;n=Iu(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),hf(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=Xu(u.source,Iu(_n.exec(u))+"g")),
-u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Iu(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++fi;return Iu(n)+t},An.upperCase=Tf,An.upperFirst=$f,An.each=nu,An.eachRight=tu,An.first=qe,Nu(An,function(){var n={};return mt(An,function(t,r){oi.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false}),An.VERSION="4.17.11",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){
-An[n].placeholder=An}),r(["drop","take"],function(n,t){Ln.prototype[n]=function(r){r=r===T?1:Li(ku(r),0);var e=this.__filtered__&&!t?new Ln(this):this.clone();return e.__filtered__?e.__takeCount__=Ci(r,e.__takeCount__):e.__views__.push({size:Ci(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Ln.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Ln.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({
-iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Ln.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Ln.prototype[n]=function(){return this.__filtered__?new Ln(this):this[r](1)}}),Ln.prototype.compact=function(){return this.filter($u)},Ln.prototype.find=function(n){return this.filter(n).head()},Ln.prototype.findLast=function(n){return this.reverse().find(n);
-},Ln.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Ln(this):this.map(function(r){return Bt(r,n,t)})}),Ln.prototype.reject=function(n){return this.filter(au(ye(n)))},Ln.prototype.slice=function(n,t){n=ku(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Ln(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=ku(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Ln.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Ln.prototype.toArray=function(){return this.take(4294967295);
-},mt(Ln.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){var t=this.__wrapped__,o=e?[1]:arguments,f=t instanceof Ln,c=o[0],l=f||ff(t),s=function(n){return n=u.apply(An,a([n],o)),e&&h?n[0]:n};l&&r&&typeof c=="function"&&1!=c.length&&(f=l=false);var h=this.__chain__,p=!!this.__actions__.length,c=i&&!h,f=f&&!p;return!i&&l?(t=f?t:new Ln(this),t=n.apply(t,o),t.__actions__.push({
-func:Qe,args:[s],thisArg:T}),new On(t,h)):c&&f?n.apply(this,o):(t=this.thru(s),c?e?t.value()[0]:t.value():t)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ri[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ff(u)?u:[],n)}return this[r](function(r){return t.apply(ff(r)?r:[],n)})}}),mt(Ln.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";
-(Gi[e]||(Gi[e]=[])).push({name:t,func:r})}}),Gi[Jr(T,2).name]=[{name:"wrapper",func:T}],Ln.prototype.clone=function(){var n=new Ln(this.__wrapped__);return n.__actions__=Lr(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Lr(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Lr(this.__views__),n},Ln.prototype.reverse=function(){if(this.__filtered__){var n=new Ln(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n;
-},Ln.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=ff(t),u=0>r,i=e?t.length:0;n=0;for(var o=i,f=this.__views__,c=-1,a=f.length;++c<a;){var l=f[c],s=l.size;switch(l.type){case"drop":n+=s;break;case"dropRight":o-=s;break;case"take":o=Ci(o,n+s);break;case"takeRight":n=Li(n,o-s)}}if(n={start:n,end:o},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ci(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);e=[];n:for(;n--&&a<l;){for(o+=r,
-u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=To,An.prototype.chain=function(){return Ye(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=mu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){for(var t,r=this;r instanceof kn;){
-var e=Fe(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Ln?(this.__actions__.length&&(n=new Ln(this)),n=n.reverse(),n.__actions__.push({func:Qe,args:[Ge],thisArg:T}),new On(n,this.__chain__)):this.thru(Ge)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,wi&&(An.prototype[wi]=Xe),
-An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this); \ No newline at end of file
+An.isSafeInteger=function(n){return vu(n)&&-9007199254740991<=n&&9007199254740991>=n},An.isSet=pf,An.isString=ju,An.isSymbol=wu,An.isTypedArray=_f,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return yu(n)&&"[object WeakMap]"==vo(n)},An.isWeakSet=function(n){return yu(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Bi.call(n,t)},An.kebabCase=Lf,An.last=Ve,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Eu(r),u=0>u?Ui(e+u,0):Ci(u,e-1)),
+t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Uf,An.lowerFirst=Cf,An.lt=vf,An.lte=gf,An.max=function(n){return n&&n.length?xt(n,$u,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,$u)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,$u,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=qu,An.stubFalse=Vu,An.stubObject=function(){return{}},An.stubString=function(){
+return""},An.stubTrue=function(){return true},An.multiply=rc,An.nth=function(n,t){return n&&n.length?Qt(n,Eu(t)):T},An.noConflict=function(){return $n._===this&&($n._=si),this},An.noop=Pu,An.now=Go,An.pad=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Ii(t),r)+n+ne(Oi(t),r))},An.padEnd=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?n+ne(t-e,r):n},An.padStart=function(n,t,r){n=Iu(n);var e=(t=Eu(t))?D(n):0;return t&&e<t?ne(t-e,r)+n:n},An.parseInt=function(n,t,r){
+return r||null==t?t=0:t&&(t=+t),Mi(Iu(n).replace(on,""),t||0)},An.random=function(n,t,r){if(r&&typeof r!="boolean"&&Oe(n,t,r)&&(t=r=T),r===T&&(typeof t=="boolean"?(r=t,t=T):typeof n=="boolean"&&(r=n,n=T)),n===T&&t===T?(n=0,t=1):(n=Au(n),t===T?(t=n,n=0):t=Au(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Ti(),Ci(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=ff(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,uo)},An.reduceRight=function(n,t,r){var e=ff(n)?s:j,u=3>arguments.length;
+return e(n,ye(t,4),r,u,io)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Eu(t),or(Iu(n),t)},An.replace=function(){var n=arguments,t=Iu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++e<u;){var i=null==n?T:n[Me(t[e])];i===T&&(e=u,i=r),n=_u(i)?i.call(n):i}return n},An.round=ec,An.runInContext=x,An.sample=function(n){return(ff(n)?Qn:cr)(n)},An.size=function(n){if(null==n)return 0;if(su(n))return ju(n)?D(n):n.length;
+var t=vo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Vt(n).length},An.snakeCase=Df,An.some=function(n,t,r){var e=ff(n)?h:pr;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.sortedIndex=function(n,t){return _r(n,t)},An.sortedIndexBy=function(n,t,r){return vr(n,t,ye(r,2))},An.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){var e=_r(n,t);if(e<r&&lu(n[e],t))return e}return-1},An.sortedLastIndex=function(n,t){return _r(n,t,true)},An.sortedLastIndexBy=function(n,t,r){return vr(n,t,ye(r,2),true);
+},An.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=_r(n,t,true)-1;if(lu(n[r],t))return r}return-1},An.startCase=Mf,An.startsWith=function(n,t,r){return n=Iu(n),r=null==r?0:pt(Eu(r),0,n.length),t=yr(t),n.slice(r,r+t.length)==t},An.subtract=uc,An.sum=function(n){return n&&n.length?m(n,$u):0},An.sumBy=function(n,t){return n&&n.length?m(n,ye(t,2)):0},An.template=function(n,t,r){var e=An.templateSettings;r&&Oe(n,t,r)&&(t=T),n=Iu(n),t=bf({},t,e,ce),r=bf({},t.imports,e.imports,ce);var u,i,o=Wu(r),f=S(r,o),c=0;
+r=t.interpolate||jn;var a="__p+='";r=Xu((t.escape||jn).source+"|"+r.source+"|"+(r===Q?pn:jn).source+"|"+(t.evaluate||jn).source+"|$","g");var l=oi.call(t,"sourceURL")?"//# sourceURL="+(t.sourceURL+"").replace(/[\r\n]/g," ")+"\n":"";if(n.replace(r,function(t,r,e,o,f,l){return e||(e=o),a+=n.slice(c,l).replace(wn,z),r&&(u=true,a+="'+__e("+r+")+'"),f&&(i=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=oi.call(t,"variable")&&t.variable)||(a="with(obj){"+a+"}"),
+a=(i?a.replace(P,""):a).replace(Z,"$1").replace(q,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(i?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=Ff(function(){return Ju(o,l+"return "+a).apply(T,f)}),t.source=a,pu(t))throw t;return t},An.times=function(n,t){if(n=Eu(n),1>n||9007199254740991<n)return[];var r=4294967295,e=Ci(n,4294967295);for(t=ye(t),n-=4294967295,e=A(e,t);++r<n;)t(r);return e},An.toFinite=Au,
+An.toInteger=Eu,An.toLength=ku,An.toLower=function(n){return Iu(n).toLowerCase()},An.toNumber=Su,An.toSafeInteger=function(n){return n?pt(Eu(n),-9007199254740991,9007199254740991):0===n?n:0},An.toString=Iu,An.toUpper=function(n){return Iu(n).toUpperCase()},An.trim=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(un,""):n&&(t=yr(t))?(n=M(n),r=M(t),t=I(n,r),r=R(n,r)+1,Or(n,t,r).join("")):n},An.trimEnd=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(fn,""):n&&(t=yr(t))?(n=M(n),t=R(n,M(t))+1,
+Or(n,0,t).join("")):n},An.trimStart=function(n,t,r){return(n=Iu(n))&&(r||t===T)?n.replace(on,""):n&&(t=yr(t))?(n=M(n),t=I(n,M(t)),Or(n,t).join("")):n},An.truncate=function(n,t){var r=30,e="...";if(du(t))var u="separator"in t?t.separator:u,r="length"in t?Eu(t.length):r,e="omission"in t?yr(t.omission):e;n=Iu(n);var i=n.length;if(Rn.test(n))var o=M(n),i=o.length;if(r>=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),hf(u)){if(n.slice(i).search(u)){
+var f=r;for(u.global||(u=Xu(u.source,Iu(_n.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},An.unescape=function(n){return(n=Iu(n))&&G.test(n)?n.replace(V,tt):n},An.uniqueId=function(n){var t=++fi;return Iu(n)+t},An.upperCase=Tf,An.upperFirst=$f,An.each=nu,An.eachRight=tu,An.first=qe,Nu(An,function(){var n={};return mt(An,function(t,r){oi.call(An.prototype,r)||(n[r]=t)}),n}(),{chain:false
+}),An.VERSION="4.17.15",r("bind bindKey curry curryRight partial partialRight".split(" "),function(n){An[n].placeholder=An}),r(["drop","take"],function(n,t){Un.prototype[n]=function(r){r=r===T?1:Ui(Eu(r),0);var e=this.__filtered__&&!t?new Un(this):this.clone();return e.__filtered__?e.__takeCount__=Ci(r,e.__takeCount__):e.__views__.push({size:Ci(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){
+var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter($u)},Un.prototype.find=function(n){
+return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n)},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(au(ye(n)))},Un.prototype.slice=function(n,t){n=Eu(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Eu(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){
+return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295)},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||ff(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;
+return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({func:Qe,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ri[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(ff(u)?u:[],n)}return this[r](function(r){return t.apply(ff(r)?r:[],n)});
+}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+"";oi.call(Gi,e)||(Gi[e]=[]),Gi[e].push({name:t,func:r})}}),Gi[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);
+n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=ff(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c<a;){var l=o[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":n-=s;break;case"take":n=Ci(n,f+s);break;case"takeRight":f=Ui(f,n-s)}}if(n={start:f,end:n},o=n.start,f=n.end,n=f-o,o=u?f:o-1,f=this.__iteratees__,c=f.length,a=0,l=Ci(n,this.__takeCount__),!e||!u&&i==n&&l==n)return wr(t,this.__actions__);
+e=[];n:for(;n--&&a<l;){for(o+=r,u=-1,i=t[o];++u<c;){var h=f[u],s=h.type,h=(0,h.iteratee)(i);if(2==s)i=h;else if(!h){if(1==s)continue n;break n}}e[a++]=i}return e},An.prototype.at=To,An.prototype.chain=function(){return Ye(this)},An.prototype.commit=function(){return new On(this.value(),this.__chain__)},An.prototype.next=function(){this.__values__===T&&(this.__values__=mu(this.value()));var n=this.__index__>=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){
+for(var t,r=this;r instanceof En;){var e=Fe(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Qe,args:[Ge],thisArg:T}),new On(n,this.__chain__)):this.thru(Ge)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,
+wi&&(An.prototype[wi]=Xe),An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js b/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js
index 9cdd5ceb9..1e8a04baf 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js
@@ -265,7 +265,8 @@ appDS2
FLAG_FLASH_REPLACE_VF_MODULE: "FLAG_FLASH_REPLACE_VF_MODULE",
FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT: "FLAG_FLASH_MORE_ACTIONS_BUTTON_IN_OLD_VIEW_EDIT",
FLAG_SHOW_ORCHESTRATION_TYPE: "FLAG_SHOW_ORCHESTRATION_TYPE",
- FLAG_2004_INSTANTIATION_TEMPLATES_POPUP : "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP"
+ FLAG_2004_INSTANTIATION_TEMPLATES_POPUP : "FLAG_2004_INSTANTIATION_TEMPLATES_POPUP",
+ FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY: "FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY"
}
};
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/InstantiationController.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/InstantiationController.js
index 673d2f6c4..f2301f582 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/InstantiationController.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/InstantiationController.js
@@ -1497,6 +1497,7 @@ Private metthods
$scope.reloadRoute();
} else {
color = FIELD.ID.COLOR_F88;
+ $scope.reloadRoute();
}
$scope.callbackStyle = {
"background-color": color
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js
index 1b6457308..a540d162a 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js
@@ -163,7 +163,7 @@
viewPerPage: $scope.viewPerPage,
currentPage: $scope.currentPage
};
- DataService.setHasTemplate(service.hasTemplate);
+ DataService.setIsInstantiationTemplateExists(service.isInstantiationTemplateExists);
sessionStorage.setItem("searchKey",JSON.stringify(searchKey));
console.log("Instantiating SDC service " + service.uuid);
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/creationDialogController.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/creationDialogController.js
index 002bcb95a..e92285311 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/creationDialogController.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/creationDialogController.js
@@ -75,10 +75,6 @@ var creationDialogController = function (COMPONENT, FIELD, PARAMETER, $scope, $h
{
$location.path('/servicePlanning').search({serviceModelId: event.data.data.serviceModelId});
}
- } else if (event.data.eventId == 'showPreviousInstantiations') {
- {
- $location.path('/instantiationStatus').search({filterText: event.data.data.serviceModelId});
- }
}
$scope.$apply();
}
@@ -93,11 +89,14 @@ var creationDialogController = function (COMPONENT, FIELD, PARAMETER, $scope, $h
if (!$scope.shouldShowOldPopup()) {
- if(DataService.getHasTemplate()){
- $scope.url = COMPONENT.INSTANTIATION_TEMPLATES_IFRAME_URL + request.modelNameVersionId;
+ let modelNameVersionId = request.modelNameVersionId ?
+ request.modelNameVersionId :
+ (DataService.getModelInfo(COMPONENT.SERVICE) ? DataService.getModelInfo(COMPONENT.SERVICE).modelNameVersionId : "");
+ if(DataService.getIsInstantiationTemplateExists()){
+ $scope.url = COMPONENT.INSTANTIATION_TEMPLATES_IFRAME_URL + modelNameVersionId;
window.addEventListener("message", receiveMessage, false);
}else {
- $scope.url = COMPONENT.SERVICE_POPUP_IFRAME_URL + request.modelNameVersionId + "&isCreate=true&r=" + Math.random();
+ $scope.url = COMPONENT.SERVICE_POPUP_IFRAME_URL + modelNameVersionId + "&isCreate=true&r=" + Math.random();
window.addEventListener("message", receiveMessage, false);
}
}
@@ -376,6 +375,7 @@ var creationDialogController = function (COMPONENT, FIELD, PARAMETER, $scope, $h
} else {
$scope.isDialogVisible = false;
$scope.popup.isVisible = false;
+ runCallback(response);
}
}
});
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/dataService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/dataService.js
index 10c4277ca..1e539ac0a 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/services/dataService.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/dataService.js
@@ -320,11 +320,11 @@ var DataService = function($log, DataService) {
setOwningEntityProperties: function (properties) {
_this.owningEntityProperties = properties;
},
- getHasTemplate: function () {
- return _this.hasTemplate;
+ getIsInstantiationTemplateExists: function () {
+ return _this.isInstantiationTemplateExists;
},
- setHasTemplate: function (hasTemplate) {
- _this.hasTemplate = hasTemplate;
+ setIsInstantiationTemplateExists: function (isInstantiationTemplateExists) {
+ _this.isInstantiationTemplateExists = isInstantiationTemplateExists;
}
};
};
diff --git a/vid-app-common/src/test/java/org/onap/vid/aai/SubscriberFilteredResultsTest.java b/vid-app-common/src/test/java/org/onap/vid/aai/SubscriberFilteredResultsTest.java
index f9668c960..06ef5d586 100644
--- a/vid-app-common/src/test/java/org/onap/vid/aai/SubscriberFilteredResultsTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/aai/SubscriberFilteredResultsTest.java
@@ -33,8 +33,10 @@ import org.onap.vid.model.SubscriberList;
import org.onap.vid.roles.EcompRole;
import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleValidator;
+import org.onap.vid.roles.RoleValidatorFactory;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
public class SubscriberFilteredResultsTest {
@@ -89,9 +91,7 @@ public class SubscriberFilteredResultsTest {
}
private void prepareRoleValidator() {
- ArrayList<Role> list = new ArrayList<>();
- list.add(new Role(EcompRole.READ, "a", "a", "a"));
- roleValidator = RoleValidator.by(list);
+ roleValidator = mock(RoleValidator.class);
}
private void prepareSubscriberList() throws IOException {
diff --git a/vid-app-common/src/test/java/org/onap/vid/bl/AaiServiceTest.java b/vid-app-common/src/test/java/org/onap/vid/bl/AaiServiceTest.java
deleted file mode 100644
index 1d4556535..000000000
--- a/vid-app-common/src/test/java/org/onap/vid/bl/AaiServiceTest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.bl;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.arrayWithSize;
-import static org.hamcrest.Matchers.equalTo;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.onap.vid.aai.AaiClientInterface;
-import org.onap.vid.aai.AaiResponse;
-import org.onap.vid.aai.model.AaiGetPnfResponse;
-import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
-import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
-import org.onap.vid.aai.model.LogicalLinkResponse;
-import org.onap.vid.aai.model.Relationship;
-import org.onap.vid.aai.model.RelationshipData;
-import org.onap.vid.aai.model.RelationshipList;
-import org.onap.vid.aai.model.ServiceRelationships;
-import org.onap.vid.roles.Role;
-import org.onap.vid.roles.RoleValidator;
-import org.onap.vid.services.AaiServiceImpl;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-public class AaiServiceTest {
-
- @InjectMocks
- private AaiServiceImpl aaiService;
-
- @Mock
- private AaiClientInterface aaiClientInterface;
-
-
-
- @BeforeMethod
- public void initMocks(){
- MockitoAnnotations.initMocks(this);
- }
-
- @Test
- public void testGetSpecificPnf(){
- Pnf pnf = Pnf.builder().withPnfId("11111").build();
- AaiResponse<Pnf> aaiResponse = new AaiResponse<>(pnf, "aaaa", 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getSpecificPnf(Mockito.anyString());
- AaiResponse<Pnf> specificPnf = aaiService.getSpecificPnf("1345667");
- assertNotNull(specificPnf);
- pnf = specificPnf.getT();
- assertNotNull(pnf);
- assertEquals("11111",pnf.getPnfId());
- assertEquals("aaaa",specificPnf.getErrorMessage());
- assertEquals(200,specificPnf.getHttpCode());
- }
-
- @Test
- public void testPnfByRegion(){
- AaiGetPnfResponse aaiGetPnfResponse = new AaiGetPnfResponse();
- AaiResponse<AaiGetPnfResponse> aaiResponse = new AaiResponse<>(aaiGetPnfResponse, "", 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getPNFData(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
- AaiResponse<AaiGetPnfResponse> aaiGetPnfResponseWrapper = aaiService.getPNFData("1345667", "1345667", "1345667", "1345667", "1345667", "1345667", "1345667");
- assertNotNull(aaiGetPnfResponseWrapper);
- aaiGetPnfResponse = aaiGetPnfResponseWrapper.getT();
- assertNotNull(aaiGetPnfResponse);
- }
-
- @Test
- public void testGetAssociatedPnfs(){
- ServiceRelationships serviceRelationships = createServiceRelationships();
- AaiResponse<ServiceRelationships> aaiResponse = new AaiResponse<>(serviceRelationships, null, 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getServiceInstance(Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
-
- LogicalLinkResponse logicalLinkResponse = createLogicalLinkResponse();
- AaiResponse<LogicalLinkResponse> aaiResponse1 = new AaiResponse<>(logicalLinkResponse, null, 200);
- Mockito.doReturn(aaiResponse1).when(aaiClientInterface).getLogicalLink("SANITY6758cce9%3ALAG1992%7CSANITY6785cce9%3ALAG1961");
-
- List<String> pnfList = aaiService.getServiceInstanceAssociatedPnfs("123", "456", "789");
- assertNotNull(pnfList);
- assertEquals(1, pnfList.size());
- assertEquals("SANITY6785cce9", pnfList.get(0));
- }
-
- private ServiceRelationships createServiceRelationships() {
- ServiceRelationships serviceRelationships = new ServiceRelationships();
- serviceRelationships.setServiceInstanceName("test service");
-
- RelationshipData logicalLinksRelationshipData = new RelationshipData();
- logicalLinksRelationshipData.setRelationshipKey("logical-link.link-name");
- logicalLinksRelationshipData.setRelationshipValue("SANITY6758cce9:LAG1992|SANITY6785cce9:LAG1961");
-
- Relationship logicalLinksRelationship = new Relationship();
- logicalLinksRelationship.setRelatedTo("logical-link");
- logicalLinksRelationship.setRelationDataList(Arrays.asList(logicalLinksRelationshipData));
-
- RelationshipList logicalLinksRelationshipsList = new RelationshipList();
- logicalLinksRelationshipsList.setRelationship(Arrays.asList(logicalLinksRelationship));
-
- serviceRelationships.setRelationshipList(logicalLinksRelationshipsList);
- return serviceRelationships;
- }
-
- private LogicalLinkResponse createLogicalLinkResponse() {
- LogicalLinkResponse logicalLinkResponse = new LogicalLinkResponse();
- logicalLinkResponse.setLinkName("SANITY6758cce9:LAG1992|SANITY6785cce9:LAG1961");
-
- RelationshipData lagInterfaceRelationshipData = new RelationshipData();
- lagInterfaceRelationshipData.setRelationshipKey("pnf.pnf-name");
- lagInterfaceRelationshipData.setRelationshipValue("SANITY6785cce9");
-
- Relationship lagInterfaceRelationship = new Relationship();
- lagInterfaceRelationship.setRelatedTo("lag-interface");
- lagInterfaceRelationship.setRelationDataList(Arrays.asList(lagInterfaceRelationshipData));
-
- RelationshipList lagInterfaceRelationshipsList = new RelationshipList();
- lagInterfaceRelationshipsList.setRelationship(Arrays.asList(lagInterfaceRelationship));
-
- logicalLinkResponse.setRelationshipList(lagInterfaceRelationshipsList);
-
- return logicalLinkResponse;
- }
-
- @DataProvider
- public static Object[][] getTenantsData() {
- return new Object[][] {
- {"customer1", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TeNant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TENANT1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "tenant2", "customer1", "serviceType1", "tenant1", "tenant2", false},
- {"customer1", "serviceType1", null, "customer1", "serviceType1", "tenant1", "tenant2", true},
- {"customer2", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", false},
- {"customer1", "serviceType2", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", false},
- {"customer2", "serviceType1", null, "customer1", "serviceType1", "tenant1", "id-1", false},
- {"customer1", "serviceType2", null, "customer1", "serviceType1", "tenant1", "id-1", false},
- };
- }
-
- @Test(dataProvider = "getTenantsData")
- public void testGetTenants(String userGlobalCustomerId, String userServiceType, String userTenantName, String serviceGlobalCustomerId,
- String serviceServiceType, String serviceTenantName, String serviceTenantId, boolean expectedIsPermitted) {
- GetTenantsResponse[] getTenantsResponses = new GetTenantsResponse[] {new GetTenantsResponse(null, null, serviceTenantName, serviceTenantId, expectedIsPermitted)};
- AaiResponse<GetTenantsResponse[]> aaiResponse = new AaiResponse<>(getTenantsResponses, null, 200);
- Mockito.doReturn(aaiResponse).when(aaiClientInterface).getTenants(serviceGlobalCustomerId, serviceServiceType);
- Role role = new Role(null, userGlobalCustomerId, userServiceType, userTenantName);
- RoleValidator roleValidator = RoleValidator.by(Collections.singletonList(role));
- AaiResponse<GetTenantsResponse[]> actualTenants = aaiService.getTenants(serviceGlobalCustomerId, serviceServiceType, roleValidator);
-
- assertThat(actualTenants.getT(), arrayWithSize(1));
- assertThat(actualTenants.getT()[0].tenantName, equalTo(serviceTenantName));
- //assertThat(actualTenants.getT()[0].isPermitted, equalTo(expectedIsPermitted));
- }
-}
diff --git a/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java b/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java
index c4f788689..3f2bf7318 100644
--- a/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java
+++ b/vid-app-common/src/test/java/org/onap/vid/config/JobCommandsConfigWithMockedMso.java
@@ -31,12 +31,32 @@ import org.onap.vid.aai.util.SystemPropertyHelper;
import org.onap.vid.dal.AsyncInstantiationRepository;
import org.onap.vid.job.JobAdapter;
import org.onap.vid.job.JobsBrokerService;
-import org.onap.vid.job.command.*;
+import org.onap.vid.job.command.ALaCarteServiceCommand;
+import org.onap.vid.job.command.CommandUtils;
+import org.onap.vid.job.command.InProgressStatusService;
+import org.onap.vid.job.command.InstanceGroupCommand;
+import org.onap.vid.job.command.InstanceGroupMemberCommand;
+import org.onap.vid.job.command.JobCommandFactory;
+import org.onap.vid.job.command.MacroServiceCommand;
+import org.onap.vid.job.command.MsoRequestBuilder;
+import org.onap.vid.job.command.MsoResultHandlerService;
+import org.onap.vid.job.command.NetworkCommand;
+import org.onap.vid.job.command.VfmoduleCommand;
+import org.onap.vid.job.command.VnfCommand;
+import org.onap.vid.job.command.VolumeGroupCommand;
+import org.onap.vid.job.command.WatchChildrenJobsBL;
import org.onap.vid.job.impl.JobAdapterImpl;
import org.onap.vid.job.impl.JobWorker;
import org.onap.vid.job.impl.JobsBrokerServiceInDatabaseImpl;
+import org.onap.vid.model.ModelUtil;
import org.onap.vid.mso.RestMsoImplementation;
-import org.onap.vid.services.*;
+import org.onap.vid.services.AsyncInstantiationBusinessLogic;
+import org.onap.vid.services.AsyncInstantiationBusinessLogicImpl;
+import org.onap.vid.services.AuditService;
+import org.onap.vid.services.AuditServiceImpl;
+import org.onap.vid.services.CloudOwnerService;
+import org.onap.vid.services.InstantiationTemplatesService;
+import org.onap.vid.services.VersionService;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -130,6 +150,18 @@ public class JobCommandsConfigWithMockedMso {
return new AsyncInstantiationBusinessLogicImpl(jobAdapter, jobsBrokerService, sessionFactory, aaiClient, featureManager, cloudOwnerService, asyncInstantiationRepository, auditService);
}
+ @Bean
+ public ModelUtil modelUtil() {return new ModelUtil();}
+
+ @Bean
+ public InstantiationTemplatesService instantiationTemplatesService(
+ ModelUtil modelUtil,
+ AsyncInstantiationRepository asyncInstantiationRepository,
+ FeatureManager featureManager
+ ) {
+ return new InstantiationTemplatesService(modelUtil, asyncInstantiationRepository, featureManager);
+ };
+
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java
index 521102383..202263c41 100644
--- a/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/controller/AaiControllerTest.java
@@ -23,11 +23,13 @@ package org.onap.vid.controller;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
@@ -68,8 +70,11 @@ import org.onap.vid.aai.model.PortDetailsTranslator.PortDetailsOk;
import org.onap.vid.aai.util.AAIRestInterface;
import org.onap.vid.model.VersionByInvariantIdsRequest;
import org.onap.vid.properties.Features;
+import org.onap.vid.roles.AlwaysValidRoleValidator;
import org.onap.vid.roles.RoleProvider;
-import org.onap.vid.roles.RoleValidatorByRoles;
+import org.onap.vid.roles.RoleValidator;
+import org.onap.vid.roles.RoleValidatorBySubscriberAndServiceType;
+import org.onap.vid.roles.RoleValidatorFactory;
import org.onap.vid.services.AaiService;
import org.onap.vid.utils.SystemPropertiesWrapper;
import org.onap.vid.utils.Unchecked;
@@ -92,6 +97,8 @@ public class AaiControllerTest {
@Mock
private RoleProvider roleProvider;
@Mock
+ private RoleValidator roleValidator;
+ @Mock
private SystemPropertiesWrapper systemPropertiesWrapper;
@Mock
private FeatureManager featureManager;
@@ -103,6 +110,7 @@ public class AaiControllerTest {
public void setUp() {
aaiController = new AaiController(aaiService, aaiRestInterface, roleProvider, systemPropertiesWrapper,
featureManager);
+ when(roleProvider.getUserRolesValidator(any())).thenReturn(roleValidator);
mockMvc = MockMvcBuilders.standaloneSetup(aaiController).build();
}
@@ -408,7 +416,7 @@ public class AaiControllerTest {
String okResponseBody = "OK_RESPONSE";
AaiResponse<String> aaiResponse = new AaiResponse<>(okResponseBody, "", HttpStatus.OK.value());
given(featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH)).willReturn(isFeatureActive);
- given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidatorByRoles.class),
+ given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidator.class),
eq(isFeatureActive && omitServiceInstances)))
.willReturn(aaiResponse);
@@ -479,7 +487,7 @@ public class AaiControllerTest {
String okResponseBody = "OK_RESPONSE";
AaiResponse<String> aaiResponse = new AaiResponse<>(okResponseBody, "", HttpStatus.OK.value());
given(featureManager.isActive(Features.FLAG_1906_AAI_SUB_DETAILS_REDUCE_DEPTH)).willReturn(isFeatureActive);
- given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidatorByRoles.class),
+ given(aaiService.getSubscriberData(eq(subscriberId), isA(RoleValidator.class),
eq(isFeatureActive && omitServiceInstances)))
.willReturn(aaiResponse);
diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/LoggerControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/LoggerControllerTest.java
index f0d840929..6f584ed3d 100644
--- a/vid-app-common/src/test/java/org/onap/vid/controller/LoggerControllerTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/controller/LoggerControllerTest.java
@@ -66,7 +66,7 @@ public class LoggerControllerTest {
@Test
public void shouldThrowNotAuthorizedException_whenUserIsNotAuthorizedToGetLogs() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(false);
@@ -80,7 +80,7 @@ public class LoggerControllerTest {
@Test
public void shouldReturnLastAndOneBeforeLogLines_whenLimitIs2() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(true);
@@ -96,7 +96,7 @@ public class LoggerControllerTest {
@Test
public void shouldReturnEmptyString_whenLogFileIsEmpty() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(true);
@@ -111,7 +111,7 @@ public class LoggerControllerTest {
@Test
public void shouldReturnEmptyString_whenDebugLogFileIsEmpty() throws Exception {
- List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1"));
+ List<Role> list = ImmutableList.of(new Role(EcompRole.READ, "subName1", "servType1", "tenant1", "owningEntityId"));
given(provider.getUserRoles(argThat(req -> req.getRequestedSessionId().equals("id1")))).willReturn(list);
given(provider.userPermissionIsReadLogs(list)).willReturn(true);
diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/ServicePermissionsTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/ServicePermissionsTest.java
index ac3da50ab..3b7dbfbb8 100644
--- a/vid-app-common/src/test/java/org/onap/vid/controller/ServicePermissionsTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/controller/ServicePermissionsTest.java
@@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
import org.jetbrains.annotations.NotNull;
import org.onap.vid.aai.model.Permissions;
+import org.onap.vid.roles.PermissionPropertiesSubscriberAndServiceType;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.roles.RoleValidator;
import org.springframework.mock.web.MockHttpServletRequest;
@@ -53,7 +54,7 @@ public class ServicePermissionsTest {
RoleProvider roleProvider = mock(RoleProvider.class);
RoleValidator roleValidator = mock(RoleValidator.class);
when(roleProvider.getUserRolesValidator(any())).thenReturn(roleValidator);
- when(roleValidator.isServicePermitted(subscriberId, serviceType)).thenReturn(expected);
+ when(roleValidator.isServicePermitted(new PermissionPropertiesSubscriberAndServiceType(subscriberId, serviceType))).thenReturn(expected);
AaiController2 aaiController2 = new AaiController2(null, roleProvider, null, null);
diff --git a/vid-app-common/src/test/java/org/onap/vid/controller/VidControllerTest.java b/vid-app-common/src/test/java/org/onap/vid/controller/VidControllerTest.java
index 484f4a034..da91edb5f 100644
--- a/vid-app-common/src/test/java/org/onap/vid/controller/VidControllerTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/controller/VidControllerTest.java
@@ -21,9 +21,27 @@
package org.onap.vid.controller;
+import static java.util.stream.Collectors.toMap;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.Matchers.not;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.BDDMockito.then;
+import static org.mockito.Mockito.times;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.IntStream;
+import javax.ws.rs.core.MediaType;
import org.apache.log4j.BasicConfigurator;
import org.junit.Assert;
import org.junit.Before;
@@ -35,35 +53,24 @@ import org.mockito.junit.MockitoJUnitRunner;
import org.onap.vid.asdc.AsdcCatalogException;
import org.onap.vid.asdc.beans.SecureServices;
import org.onap.vid.asdc.beans.Service;
-import org.onap.vid.model.*;
+import org.onap.vid.model.CR;
+import org.onap.vid.model.Network;
+import org.onap.vid.model.Node;
import org.onap.vid.model.PombaInstance.PombaRequest;
import org.onap.vid.model.PombaInstance.ServiceInstance;
+import org.onap.vid.model.ServiceModel;
+import org.onap.vid.model.ServiceProxy;
+import org.onap.vid.model.VNF;
+import org.onap.vid.model.VfModule;
+import org.onap.vid.model.VolumeGroup;
import org.onap.vid.roles.RoleProvider;
import org.onap.vid.services.AaiService;
+import org.onap.vid.services.InstantiationTemplatesService;
import org.onap.vid.services.PombaService;
import org.onap.vid.services.VidService;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import javax.ws.rs.core.MediaType;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.stream.IntStream;
-
-import static java.util.stream.Collectors.toMap;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.Matchers.not;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.BDDMockito.then;
-import static org.mockito.Mockito.times;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
@RunWith(MockitoJUnitRunner.class)
public class VidControllerTest {
@@ -79,6 +86,8 @@ public class VidControllerTest {
private RoleProvider roleProvider;
@Mock
private PombaService pombaService;
+ @Mock
+ private InstantiationTemplatesService instantiationTemplatesService;
private VidController vidController;
private MockMvc mockMvc;
@@ -90,7 +99,7 @@ public class VidControllerTest {
@Before
public void setUp() {
- vidController = new VidController(vidService, aaiService, roleProvider, pombaService);
+ vidController = new VidController(vidService, aaiService, roleProvider, pombaService, instantiationTemplatesService);
BasicConfigurator.configure();
mockMvc = MockMvcBuilders.standaloneSetup(vidController).build();
objectMapper = new ObjectMapper();
@@ -102,12 +111,17 @@ public class VidControllerTest {
@Test
public void getServices_shouldReturnService_whenServiceExists() throws Exception {
- List<Service> services = ImmutableList.of(createService(uuid1, 1), createService(uuid2, 2), createService(uuid3, 3));
+ List<Service> services1 = ImmutableList.of(createService(uuid1, 1), createService(uuid2, 2), createService(uuid3, 3));
+ List<Service> services2 = ImmutableList.of(createService(uuid1, 4), createService(uuid2, 5), createService(uuid3, 6));
+
+ given(aaiService.getServicesByDistributionStatus())
+ .willReturn(services1);
- given(aaiService.getServicesByDistributionStatus()).willReturn(services);
+ given(instantiationTemplatesService.setOnEachServiceIsTemplateExists(services1))
+ .willReturn(services2);
SecureServices secureServices = new SecureServices();
- secureServices.setServices(services);
+ secureServices.setServices(services2);
secureServices.setReadOnly(false);
mockMvc.perform(get(REST_MODELS_SERVICES)
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java
index db856d757..b916347d2 100644
--- a/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/ResourceCommandTest.java
@@ -279,7 +279,7 @@ public class ResourceCommandTest {
convertToMap(networks),
convertToMap(vnfGroups),
null,
- null, false, 1, false,false,null, null, null, null, null, null, null);
+ null, false, 1, false,false,null, null, null, null, null, null, null, null);
}
public static ServiceInstantiation createServiceWith2InstancesInEachLevel(Action action) {
@@ -298,11 +298,11 @@ public class ResourceCommandTest {
static InstanceGroup createGroup(List<InstanceGroupMember> groupMembers, Action action) {
return new InstanceGroup(mock(ModelInfo.class), null, action.name(), false, null, convertToMap(groupMembers), null, null, null,
- null);
+ null, null);
}
static InstanceGroupMember createMember(Action action) {
- return new InstanceGroupMember(null, action.toString(), null, null, null, null);
+ return new InstanceGroupMember(null, action.toString(), null, null, null, null, null);
}
static Vnf createVnf(List<VfModule> vfModules, Action action) {
@@ -310,22 +310,22 @@ public class ResourceCommandTest {
vfModulesMap.put("abc",convertToMap(vfModules));
return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, vfModulesMap, null, null, null,
- null);
+ null, null);
}
static Vnf createVnf(Action action) {
return new Vnf(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null,null, null, null, null,
- null);
+ null, null);
}
static VfModule createVfModule(Action action) {
return new VfModule(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null,
- false, false, null, null, null, null, null, null, null);
+ false, false, null, null, null, null, null, null, null, null);
}
static Network createNetwork(Action action) {
return new Network(mock(ModelInfo.class), null, null, action.toString(), null, null, null, null, null, null, false, null, null, null, null,
- null);
+ null, null);
}
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt b/vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt
new file mode 100644
index 000000000..660abe4d2
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/job/command/VnfCommandTest.kt
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.job.command
+
+import net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.core.AllOf.allOf
+import org.mockito.Answers
+import org.mockito.InjectMocks
+import org.mockito.Mock
+import org.onap.vid.job.JobAdapter
+import org.onap.vid.job.JobsBrokerService
+import org.onap.vid.job.command.ResourceCommandTest.FakeResourceCreator
+import org.onap.vid.job.impl.JobSharedData
+import org.onap.vid.model.Action
+import org.onap.vid.mso.RestMsoImplementation
+import org.onap.vid.properties.Features
+import org.onap.vid.services.AsyncInstantiationBusinessLogic
+import org.onap.vid.testUtils.TestUtils
+import org.onap.vid.testUtils.TestUtils.initMockitoMocks
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+import org.togglz.core.manager.FeatureManager
+import org.mockito.Mockito.`when` as _when
+
+class VnfCommandTest {
+
+ @Mock lateinit var asyncInstantiationBL: AsyncInstantiationBusinessLogic
+ @Mock lateinit var restMso: RestMsoImplementation
+ @Mock lateinit var msoRequestBuilder: MsoRequestBuilder
+ @Mock lateinit var msoResultHandlerService: MsoResultHandlerService
+ @Mock lateinit var inProgressStatusService:InProgressStatusService
+ @Mock lateinit var watchChildrenJobsBL: WatchChildrenJobsBL
+ @Mock lateinit var jobsBrokerService: JobsBrokerService
+ @Mock lateinit var jobAdapter: JobAdapter
+ @Mock lateinit var featureManager: FeatureManager
+
+ @Mock lateinit var jobSharedData: JobSharedData
+ @Mock(answer = Answers.RETURNS_MOCKS) lateinit var vnfJobRequest: org.onap.vid.model.serviceInstantiation.Vnf
+
+ @InjectMocks lateinit var vnfCommand: VnfCommand;
+
+ @BeforeMethod
+ fun initMocks() {
+ initMockitoMocks(this)
+ }
+
+ @Test(dataProvider = "trueAndFalse", dataProviderClass = TestUtils::class)
+ fun `childVfModuleWithVnfRegionAndTenant -- given vfmodule -- tenant and region are copied from vnf`(featureToggleOn: Boolean) {
+
+ val vfModule = FakeResourceCreator.createVfModule(Action.Create)
+ .cloneWith("vfmodule-lcp-cloud-region-id", "vfmodule-tenant-id")
+
+ _when(featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(featureToggleOn)
+
+ _when(vnfJobRequest.lcpCloudRegionId).thenReturn("vnf-lcp-cloud-region-id")
+ _when(vnfJobRequest.tenantId).thenReturn("vnf-tenant-id")
+ _when(jobSharedData.request).thenReturn(vnfJobRequest)
+
+ vnfCommand.init(jobSharedData, mapOf())
+
+ val expectedSource = if (featureToggleOn) "vnf" else "vfmodule"
+
+ assertThat(vnfCommand.childVfModuleWithVnfRegionAndTenant(vfModule),
+ allOf(
+ jsonPartEquals("lcpCloudRegionId", "${expectedSource}-lcp-cloud-region-id"),
+ jsonPartEquals("tenantId", "${expectedSource}-tenant-id")
+ )
+ )
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java b/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java
index cd4045b8d..642adb307 100644
--- a/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/job/impl/AsyncInstantiationIntegrationTest.java
@@ -59,6 +59,7 @@ import static org.onap.vid.job.Job.JobStatus.STOPPED;
import static org.onap.vid.job.impl.JobSchedulerInitializer.WORKERS_TOPICS;
import static org.onap.vid.model.JobAuditStatus.SourceStatus.VID;
import static org.onap.vid.testUtils.TestUtils.readJsonResourceFileAsObject;
+import static org.testng.Assert.assertNull;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertTrue;
@@ -119,6 +120,7 @@ import org.onap.vid.properties.Features;
import org.onap.vid.services.AsyncInstantiationBaseTest;
import org.onap.vid.services.AsyncInstantiationBusinessLogic;
import org.onap.vid.services.AuditService;
+import org.onap.vid.services.InstantiationTemplatesService;
import org.onap.vid.services.VersionService;
import org.onap.vid.testUtils.TestUtils;
import org.onap.vid.utils.DaoUtils;
@@ -172,6 +174,9 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
@Inject
private CommandUtils commandUtils;
+ @Inject
+ private InstantiationTemplatesService instantiationTemplates;
+
@BeforeClass
void initServicesInfoService() {
createInstanceParamsMaps();
@@ -189,7 +194,12 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
void defineMocks() {
Mockito.reset(restMso);
Mockito.reset(aaiClient);
+ Mockito.reset(commandUtils);
mockAaiClientAnyNameFree();
+
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
+ when(featureManager.isActive(Features.FLAG_2006_VFMODULE_TAKES_TENANT_AND_REGION_FROM_VNF)).thenReturn(true);
}
@Test
@@ -371,9 +381,7 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
* not looking on audit (yet)
*/
- reset(restMso);
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false);
+ when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(false); // this makes the test pass without mocking the vfModules
final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
final String VNF_REQUEST_ID = UUID.randomUUID().toString();
@@ -416,8 +424,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
String msoVnfStatus = COMPLETE_STR;
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VNF)).thenReturn(true);
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
final String SERVICE_INSTANCE_ID = UUID.randomUUID().toString();
final String VNF_REQUEST_ID = UUID.randomUUID().toString();
@@ -431,7 +437,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
//push alacarte with 1 vnf, verify STATUS pending
UUID uuid = pushALaCarteWithVnf();
singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
- reset(restMso);
/*---------- service -----------*/
@@ -514,8 +519,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
NetworkDetails networkDetails1 = new NetworkDetails("LukaDoncic", "1");
NetworkDetails networkDetails2 = new NetworkDetails("KevinDurant", "2");
- reset(restMso);
-
/*---------- service -----------*/
//mock mso to answer 200 of create service instance request, verify STATUS in progress
@@ -1014,8 +1017,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
JobStatus expectedJobStatus,
int getStatusCounter) throws IOException, AsdcCatalogException {
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
- reset(commandUtils);
when(commandUtils.isVfModuleBaseModule("6b528779-44a3-4472-bdff-9cd15ec93450", "f8360508-3f17-4414-a2ed-6bc71161e8db")).thenReturn(true);
when(commandUtils.isVfModuleBaseModule("6b528779-44a3-4472-bdff-9cd15ec93450", "25284168-24bb-4698-8cb4-3f509146eca5")).thenReturn(false);
@@ -1266,7 +1267,6 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
asyncRequestStatusResponseAsRestObject(IN_PROGRESS_STR),
asyncRequestStatusResponseAsRestObject(COMPLETE_STR));
- when(featureManager.isActive(Features.FLAG_ASYNC_ALACARTE_VFMODULE)).thenReturn(true);
enableAddCloudOwnerOnMsoRequest();
@@ -1309,4 +1309,41 @@ public class AsyncInstantiationIntegrationTest extends AsyncInstantiationBaseTes
return readJsonResourceFileAsObject("/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json", ServiceInstantiation.class);
}
+ @Test
+ public void deployService_failIt_retryDeploy_getRetryAsTemplate_makeSureFalsyIsFailedInTemplate() {
+
+ final String SERVICE_REQUEST_ID = UUID.randomUUID().toString();
+
+ //push alacarte with 1 vnf, verify STATUS pending
+ UUID uuid = pushALaCarteWithVnf();
+ singleServicesAndAssertStatus(JobStatus.PENDING, uuid);
+
+ //mock mso to answer 200 of create service instance request, verify STATUS in progress
+ when(restMso.restCall(eq(HttpMethod.POST), eq(RequestReferencesContainer.class), any(), endsWith("serviceInstances"), any())).thenReturn(
+ createResponse(200, SERVICE_INSTANCE_ID, SERVICE_REQUEST_ID));
+
+ //mock mso to answer FAILED for service instance create
+ final RestObject<AsyncRequestStatus> failedResponse = asyncRequestStatusResponseAsRestObject(FAILED_STR);
+ final String failureDescription = "Some deep failure";
+ failedResponse.get().request.requestStatus.setStatusMessage(failureDescription);
+ when(restMso.GetForObject(endsWith(SERVICE_REQUEST_ID), eq(AsyncRequestStatus.class))).
+ thenReturn(failedResponse);
+
+ //Wait till job failed
+ processJobsCountTimesAndAssertStatus(uuid, 3, FAILED);
+
+ //make sure retry request jas isFailed = true, and status message is with failureDescription
+ ServiceInstantiation retryRequest = asyncInstantiationBL.getBulkForRetry(uuid);
+ assertTrue(retryRequest.getIsFailed());
+ assertEquals(failureDescription, retryRequest.getStatusMessage());
+
+ //deploy retry job and it's template
+ UUID retryUuid = asyncInstantiationBL.pushBulkJob(retryRequest, USER_ID).get(0);
+ ServiceInstantiation templateOfRetry = instantiationTemplates.getJobRequestAsTemplate(retryUuid);
+
+ //make sure the template request has isFailed = false, and no status message
+ assertFalse(templateOfRetry.getIsFailed());
+ assertNull(templateOfRetry.getStatusMessage());
+ }
+
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/model/ServiceInstanceSearchResultTest.java b/vid-app-common/src/test/java/org/onap/vid/model/ServiceInstanceSearchResultTest.java
index 5168a5c63..b777375ef 100644
--- a/vid-app-common/src/test/java/org/onap/vid/model/ServiceInstanceSearchResultTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/model/ServiceInstanceSearchResultTest.java
@@ -20,183 +20,47 @@
package org.onap.vid.model;
-import org.junit.Test;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanConstructor;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanEqualsFor;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidBeanHashCodeFor;
+import static com.google.code.beanmatchers.BeanMatchers.hasValidGettersAndSetters;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonNodeAbsent;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
+import static org.apache.commons.lang3.ArrayUtils.toArray;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
public class ServiceInstanceSearchResultTest {
- private ServiceInstanceSearchResult createTestSubject() {
- return new ServiceInstanceSearchResult();
- }
-
- @Test
- public void testGetServiceInstanceId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getServiceInstanceId();
- }
-
- @Test
- public void testSetServiceInstanceId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String serviceInstanceId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setServiceInstanceId(serviceInstanceId);
- }
-
- @Test
- public void testGetGlobalCustomerId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getGlobalCustomerId();
- }
-
- @Test
- public void testSetGlobalCustomerId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String globalCustomerId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setGlobalCustomerId(globalCustomerId);
- }
-
- @Test
- public void testGetServiceType() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getServiceType();
- }
-
- @Test
- public void testSetServiceType() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String serviceType = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setServiceType(serviceType);
- }
-
- @Test
- public void testGetServiceInstanceName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getServiceInstanceName();
- }
-
- @Test
- public void testSetServiceInstanceName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String serviceInstanceName = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setServiceInstanceName(serviceInstanceName);
- }
-
- @Test
- public void testGetSubscriberName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getSubscriberName();
- }
-
- @Test
- public void testSetSubscriberName() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String subscriberName = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setSubscriberName(subscriberName);
- }
-
@Test
- public void testGetAaiModelInvariantId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getAaiModelInvariantId();
- }
-
- @Test
- public void testSetAaiModelInvariantId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String aaiModelInvariantId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setAaiModelInvariantId(aaiModelInvariantId);
- }
-
- @Test
- public void testGetAaiModelVersionId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getAaiModelVersionId();
+ public void shouldHaveValidGettersAndSetters() {
+ assertThat(ServiceInstanceSearchResult.class, hasValidGettersAndSetters());
}
@Test
- public void testSetAaiModelVersionId() throws Exception {
- ServiceInstanceSearchResult testSubject;
- String aaiModelVersionId = "";
-
- // default test
- testSubject = createTestSubject();
- testSubject.setAaiModelVersionId(aaiModelVersionId);
- }
-
- @Test
- public void testGetIsPermitted() throws Exception {
- ServiceInstanceSearchResult testSubject;
- boolean result;
-
- // default test
- testSubject = createTestSubject();
- result = testSubject.getIsPermitted();
+ public void shouldHaveValidConstructor() {
+ assertThat(ServiceInstanceSearchResult.class, hasValidBeanConstructor());
}
@Test
- public void testSetIsPermitted() throws Exception {
- ServiceInstanceSearchResult testSubject;
- boolean isPermitted = false;
+ public void shouldHaveValidEqualsAndHashCode() {
+ String[] propertiesToEqualBy = toArray("serviceInstanceId");
- // default test
- testSubject = createTestSubject();
- testSubject.setIsPermitted(isPermitted);
+ assertThat(ServiceInstanceSearchResult.class, allOf(
+ hasValidBeanHashCodeFor(propertiesToEqualBy),
+ hasValidBeanEqualsFor(propertiesToEqualBy))
+ );
}
@Test
- public void testEquals() throws Exception {
- ServiceInstanceSearchResult testSubject;
- Object other = null;
- boolean result;
+ public void subscriberId_shouldBeSerializedAsGlobalCustomerId() {
+ ServiceInstanceSearchResult underTest = new ServiceInstanceSearchResult();
+ underTest.setSubscriberId("example");
- // default test
- testSubject = createTestSubject();
- result = testSubject.equals(other);
+ assertThat(underTest, jsonPartEquals("globalCustomerId", "example"));
+ assertThat(underTest, jsonNodeAbsent("subscriberId"));
}
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/InstantiationModelSerializationTest.java b/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/InstantiationModelSerializationTest.java
index b5d281622..f0c96b839 100644
--- a/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/InstantiationModelSerializationTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/InstantiationModelSerializationTest.java
@@ -38,6 +38,7 @@ import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.lang.reflect.InvocationTargetException;
+import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.onap.vid.model.VidNotions;
@@ -45,6 +46,7 @@ import org.onap.vid.model.VidNotions.InstantiationType;
import org.onap.vid.model.VidNotions.InstantiationUI;
import org.onap.vid.model.VidNotions.ModelCategory;
import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
import org.testng.annotations.Test;
public class InstantiationModelSerializationTest {
@@ -92,7 +94,8 @@ public class InstantiationModelSerializationTest {
new VidNotions(InstantiationUI.ANY_ALACARTE_WHICH_NOT_EXCLUDED,
ModelCategory.INFRASTRUCTURE_VPN,
InstantiationUI.INFRASTRUCTURE_VPN,
- InstantiationType.Macro)
+ InstantiationType.Macro),
+ "originalName"
);
verifySerializationAndDeserialization(serviceInstantiation);
@@ -117,7 +120,8 @@ public class InstantiationModelSerializationTest {
"trackById",
true,
"statusMessage",
- 5);
+ 5,
+ "originalName");
verifySerializationAndDeserialization(vnf);
}
@@ -125,10 +129,10 @@ public class InstantiationModelSerializationTest {
@Test
public void serializeAndDeserializeVfModule() throws Exception {
- ImmutableMap<String, String> supplementaryParams = ImmutableMap.of(
- "uno", "1",
- "dos", "2",
- "tres", "3"
+ List<UserParamNameAndValue> supplementaryParams = ImmutableList.of(
+ new UserParamNameAndValue("uno", "1"),
+ new UserParamNameAndValue("dos", "2"),
+ new UserParamNameAndValue("tres", "3")
);
VfModule vfModule = new VfModule(
@@ -149,7 +153,8 @@ public class InstantiationModelSerializationTest {
"statusMessage",
true,
true,
- 1);
+ 1,
+ "originalName");
verifySerializationAndDeserialization(vfModule);
}
@@ -162,7 +167,7 @@ public class InstantiationModelSerializationTest {
VfModule vfModule = new VfModule(newModelInfo(), null, null, null,
null, null, null, null, null, false,
/* HERE ====> */ USE_PRELOAD,
- null, null, null, null, null, null, null);
+ null, null, null, null, null, null, null, null);
assertThat(vfModule, jsonPartEquals("sdncPreLoad", USE_PRELOAD));
assertThat(vfModule, jsonNodeAbsent("usePreload"));
@@ -177,7 +182,7 @@ public class InstantiationModelSerializationTest {
/* HERE ====> */ VOLUME_GROUP_INSTANCE_NAME,
null, null, null, null, null, null,
false, null, null, null, null, null,
- null, null, null);
+ null, null, null, null);
assertThat(vfModule, jsonPartEquals("volumeGroupName", VOLUME_GROUP_INSTANCE_NAME));
assertThat(vfModule, jsonNodeAbsent("volumeGroupInstanceName"));
diff --git a/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java b/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java
new file mode 100644
index 000000000..a1c78c421
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/model/serviceInstantiation/VfModuleTest.java
@@ -0,0 +1,62 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.model.serviceInstantiation;
+
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.beans.HasPropertyWithValue.hasProperty;
+import static org.hamcrest.core.AllOf.allOf;
+import static org.onap.vid.testUtils.TestUtils.setStringsInStringProperties;
+
+import org.onap.vid.mso.model.ModelInfo;
+import org.testng.annotations.Test;
+
+public class VfModuleTest {
+
+ @Test
+ public void cloneWithLcpCloudRegionIdAndTenantId() {
+ String targetLcpCloudRegionId = "dictated lcpCloudRegionId";
+ String targetTenantId = "dictated tenantId";
+
+ VfModule originVfModule = createVfModule();
+
+ assertThat(originVfModule.cloneWith(targetLcpCloudRegionId, targetTenantId), allOf(
+ hasProperty("lcpCloudRegionId", equalTo(targetLcpCloudRegionId)),
+ hasProperty("tenantId", equalTo(targetTenantId)),
+ jsonEquals(originVfModule).whenIgnoringPaths("lcpCloudRegionId", "tenantId")
+ ));
+
+ // verify vfModule did not mutate
+ assertThat(originVfModule, jsonEquals(createVfModule()));
+ }
+
+ private VfModule createVfModule() {
+ VfModule vfModule = new VfModule(
+ setStringsInStringProperties(new ModelInfo()),
+ null, null, null, null, null,
+ null, null, null, true, true,
+ null, null, true, null, true,
+ true, null, null);
+
+ return setStringsInStringProperties(vfModule);
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/MsoUtilTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/MsoUtilTest.java
index 10456bebf..cfde52a56 100644
--- a/vid-app-common/src/test/java/org/onap/vid/mso/MsoUtilTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/mso/MsoUtilTest.java
@@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.joshworks.restclient.http.HttpResponse;
import org.onap.vid.testUtils.TestUtils;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class MsoUtilTest {
@@ -67,4 +68,26 @@ public class MsoUtilTest {
assertThat(result.getStatus()).isEqualTo(SC_OK);
}
+ @DataProvider
+ public static Object[][] formatExceptionAdditionalInfo() {
+ return new Object[][]{
+ {"message", "Http Code:400, message"},
+
+ {null, "Http Code:400"},
+
+ {"{\"requestError\":{\"serviceException\":{\"messageId\":\"SVC0002\",\"text\":\"message\"}}}",
+ "Http Code:400, \"messageId\":\"SVC0002\",\"text\":\"message\""},
+
+ {"{\"validJson\": \"Error: message\"}", "Http Code:400, {\"validJson\": \"Error: message\"}"},
+
+ {"{\"serviceException\":{\"messageId\":\"SVC0002\",\"text\":\"Error: message\"}}",
+ "Http Code:400, \"messageId\":\"SVC0002\",\"text\":\"Error: message\""},
+ };
+ }
+
+ @Test(dataProvider = "formatExceptionAdditionalInfo")
+ public void formatExceptionAdditionalInfo_payloadWithError400_doNotReturnNull(String payload, String expected) {
+ assertThat(MsoUtil.formatExceptionAdditionalInfo(400, payload))
+ .isEqualTo(expected);
+ }
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/mso/model/RequestParametersVfModuleTest.java b/vid-app-common/src/test/java/org/onap/vid/mso/model/RequestParametersVfModuleTest.java
new file mode 100644
index 000000000..e339af094
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/mso/model/RequestParametersVfModuleTest.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.mso.model;
+
+import static java.util.Collections.emptyList;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import org.testng.annotations.Test;
+
+public class RequestParametersVfModuleTest {
+
+ @Test
+ public void RequestParametersVfModuleOrVolumeGroupInstantiation_whenUsePreloadIsNull_thenLiteralFalseIsSerialized() {
+ Boolean usePreload = null;
+ assertThat(
+ new RequestParametersVfModuleOrVolumeGroupInstantiation(emptyList(), usePreload, ""),
+ jsonPartEquals("usePreload", false)
+ );
+ }
+
+ @Test
+ public void RequestParametersVfModuleUpgrade_whenUsePreloadIsNull_thenLiteralFalseIsSerialized() {
+ Boolean usePreload = null;
+ assertThat(
+ new RequestParametersVfModuleUpgrade(emptyList(), usePreload, "", false, false),
+ jsonPartEquals("usePreload", false)
+ );
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/properties/FeatureSetsManagerTest.kt b/vid-app-common/src/test/java/org/onap/vid/properties/FeatureSetsManagerTest.kt
new file mode 100644
index 000000000..9cf7aa662
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/properties/FeatureSetsManagerTest.kt
@@ -0,0 +1,101 @@
+package org.onap.vid.properties
+
+import org.hamcrest.CoreMatchers.*
+import org.hamcrest.MatcherAssert.assertThat
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.InjectMocks
+import org.mockito.Mock
+import org.mockito.Mockito.*
+import org.onap.vid.testUtils.TestUtils
+import org.springframework.web.context.request.RequestContextHolder
+import org.testng.annotations.BeforeMethod
+import org.testng.annotations.Test
+import org.togglz.core.manager.FeatureManager
+import javax.servlet.ServletContext
+import javax.servlet.http.Cookie
+import javax.servlet.http.HttpServletRequest
+import org.hamcrest.CoreMatchers.`is` as _is
+import org.mockito.Mockito.`when` as _when
+
+class FeatureSetsManagerTest {
+ @Mock
+ lateinit var defaultFeatureManager: FeatureManager
+ @Mock
+ lateinit var servletContext: ServletContext
+ @Mock
+ lateinit var alternativeFeatureSetNameProvider: AlternativeFeatureSetNameProvider
+ @InjectMocks
+ lateinit var featureSetsManager: FeatureSetsManager
+
+ private val alternativeFeatureSetNameFromCookie = AlternativeFeatureSetNameFromCookie()
+
+ @BeforeMethod
+ fun setUp() {
+ TestUtils.initMockitoMocks(this)
+ }
+
+ @Test
+ fun `isActive - without alternative features set name - delegates to default and no file loaded`() {
+ _when(defaultFeatureManager.isActive(Features.FLAG_1810_AAI_LOCAL_CACHE)).thenReturn(true)
+ _when(alternativeFeatureSetNameProvider.alternativeFeatureSetName).thenReturn(null)
+
+ assertThat(featureSetsManager.isActive(Features.FLAG_1810_AAI_LOCAL_CACHE), _is(true))
+
+ verifyZeroInteractions(servletContext) // implies no other file loaded
+ verify(defaultFeatureManager, times(1)).isActive(Features.FLAG_1810_AAI_LOCAL_CACHE)
+ }
+
+ @Test
+ fun `isActive - with alternative features set - brings flags from alternative`() {
+ _when(servletContext.getRealPath(anyString())).thenReturn(this.javaClass.getResource("/").path)
+ _when(alternativeFeatureSetNameProvider.alternativeFeatureSetName).thenReturn("example.features.properties")
+
+ assertThat(featureSetsManager.isActive(Features.FLAG_1810_AAI_LOCAL_CACHE), _is(true))
+ assertThat(featureSetsManager.isActive(Features.FLAG_1902_NEW_VIEW_EDIT), _is(false))
+ verifyZeroInteractions(defaultFeatureManager)
+ }
+
+ @Test
+ fun `isActive - with non-existing alternative features set - fallback is to all flags off`() {
+ _when(servletContext.getRealPath(anyString())).thenReturn(this.javaClass.getResource("/").path)
+ _when(alternativeFeatureSetNameProvider.alternativeFeatureSetName).thenReturn("non-existing")
+
+ assertThat(featureSetsManager, not(nullValue()))
+ assertThat(
+ featureSetsManager.features.map { featureSetsManager.isActive(it) },
+ not(hasItem(true))
+ )
+ }
+
+ @Test
+ fun `valueFromCookie - given no request - return null`() {
+ assertThat(alternativeFeatureSetNameFromCookie.valueFromCookie(null), _is(nullValue()))
+ }
+
+ @Test
+ fun `valueFromCookie - given request - return the correct cookie value`() {
+ val servletRequestMock = mock(HttpServletRequest::class.java)
+ _when(servletRequestMock.cookies).thenReturn(arrayOf(Cookie("features.set", "value")))
+
+ assertThat(alternativeFeatureSetNameFromCookie.valueFromCookie(servletRequestMock), _is("value"))
+ }
+
+ @Test
+ fun `valueFromCookie - given request without cookies - return null`() {
+ val servletRequestMock = mock(HttpServletRequest::class.java)
+ _when(servletRequestMock.cookies).thenReturn(emptyArray())
+
+ assertThat(alternativeFeatureSetNameFromCookie.valueFromCookie(servletRequestMock), _is(nullValue()))
+ }
+
+ @Test
+ fun `currentHttpRequest - when no current request - return null`() {
+ assertPrecondition()
+ assertThat(alternativeFeatureSetNameFromCookie.currentHttpRequest(), _is(nullValue()))
+ }
+
+ private fun assertPrecondition() {
+ assertThat("precondition for test not met: static RequestContextHolder.getRequestAttributes should be null",
+ RequestContextHolder.getRequestAttributes(), _is(nullValue()))
+ }
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/AlwaysValidRoleValidatorTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/AlwaysValidRoleValidatorTest.java
index 363c6ff76..6826b1e4a 100644
--- a/vid-app-common/src/test/java/org/onap/vid/roles/AlwaysValidRoleValidatorTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/roles/AlwaysValidRoleValidatorTest.java
@@ -33,7 +33,8 @@ public class AlwaysValidRoleValidatorTest {
@Test
public void testIsServicePermitted() {
- assertTrue(new AlwaysValidRoleValidator().isServicePermitted("any", "any"));
+ WithPermissionProperties emptyPermissionProperties = new WithPermissionProperties() {};
+ assertTrue(new AlwaysValidRoleValidator().isServicePermitted(emptyPermissionProperties));
}
@Test
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/RoleProviderTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/RoleProviderTest.java
index c1033d2d0..8d81c929c 100644
--- a/vid-app-common/src/test/java/org/onap/vid/roles/RoleProviderTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/roles/RoleProviderTest.java
@@ -22,6 +22,7 @@ package org.onap.vid.roles;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@@ -42,7 +43,7 @@ import org.testng.annotations.Test;
public class RoleProviderTest {
private static final String SAMPLE_SUBSCRIBER = "sampleSubscriber";
- private static final String SAMPLE_CUSTOMER_ID = "sampleCustomerId";
+ private static final String SAMPLE_SUBSCRIBER_ID = "subscriberId";
private static final String SERVICE_TYPE_LOGS = "LOGS";
private static final String TENANT_PERMITTED = "PERMITTED";
private static final String SAMPLE_SERVICE = "sampleService";
@@ -58,13 +59,16 @@ public class RoleProviderTest {
@Mock
private AaiResponse<SubscriberList> subscriberListResponse;
+ @Mock
+ private RoleValidatorFactory roleValidatorFactory;
+
private RoleProvider roleProvider;
@BeforeMethod
public void setUp() {
initMocks(this);
- roleProvider = new RoleProvider(aaiService, httpServletRequest -> 5, httpServletRequest -> createRoles());
+ roleProvider = new RoleProvider(aaiService, roleValidatorFactory, httpServletRequest -> 5, httpServletRequest -> createRoles());
}
@Test
@@ -83,7 +87,7 @@ public class RoleProviderTest {
Role role = roleProvider.createRoleFromStringArr(roleParts, SAMPLE_ROLE_PREFIX);
assertThat(role.getEcompRole()).isEqualTo(EcompRole.READ);
- assertThat(role.getSubscribeName()).isEqualTo(SAMPLE_CUSTOMER_ID);
+ assertThat(role.getSubscriberId()).isEqualTo(SAMPLE_SUBSCRIBER_ID);
assertThat(role.getTenant()).isEqualTo(SAMPLE_TENANT);
assertThat(role.getServiceType()).isEqualTo(SAMPLE_SERVICE);
}
@@ -97,7 +101,7 @@ public class RoleProviderTest {
Role role = roleProvider.createRoleFromStringArr(roleParts, SAMPLE_ROLE_PREFIX);
assertThat(role.getEcompRole()).isEqualTo(EcompRole.READ);
- assertThat(role.getSubscribeName()).isEqualTo(SAMPLE_CUSTOMER_ID);
+ assertThat(role.getSubscriberId()).isEqualTo(SAMPLE_SUBSCRIBER_ID);
assertThat(role.getServiceType()).isEqualTo(SAMPLE_SERVICE);
assertThat(role.getTenant()).isNullOrEmpty();
}
@@ -111,7 +115,7 @@ public class RoleProviderTest {
@Test
public void shouldProperlyRetrieveUserRolesWhenPermissionIsDifferentThanRead() {
- Role expectedRole = new Role(EcompRole.READ, SAMPLE_CUSTOMER_ID, SAMPLE_SERVICE, SAMPLE_TENANT);
+ Role expectedRole = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER_ID, SAMPLE_SERVICE, SAMPLE_TENANT, owningEntityId());
setSubscribers();
List<Role> userRoles = roleProvider.getUserRoles(request);
@@ -121,7 +125,7 @@ public class RoleProviderTest {
Role actualRole = userRoles.get(0);
assertThat(actualRole.getTenant()).isEqualTo(expectedRole.getTenant());
- assertThat(actualRole.getSubscribeName()).isEqualTo(expectedRole.getSubscribeName());
+ assertThat(actualRole.getSubscriberId()).isEqualTo(expectedRole.getSubscriberId());
assertThat(actualRole.getServiceType()).isEqualTo(expectedRole.getServiceType());
}
@@ -132,21 +136,38 @@ public class RoleProviderTest {
@Test
public void shouldReturnNotReadOnlyPermissionWhenRolesArePresent() {
- assertThat(roleProvider.userPermissionIsReadOnly(Lists.list(new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT)))).isFalse();
+ assertThat(roleProvider.userPermissionIsReadOnly(Lists.list(new Role(
+ EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT, owningEntityId())))).isFalse();
}
@Test
public void userShouldHavePermissionToReadLogsWhenServiceAndTenantAreCorrect() {
- Role withoutPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT);
- Role withPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SERVICE_TYPE_LOGS, TENANT_PERMITTED);
+ Role withoutPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE, SAMPLE_TENANT, owningEntityId());
+ Role withPermission = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SERVICE_TYPE_LOGS, TENANT_PERMITTED, owningEntityId());
assertThat(roleProvider.userPermissionIsReadLogs(Lists.list(withoutPermission, withPermission))).isTrue();
}
+ @Test
+ public void getUserRolesValidator_shouldReturnValidatorFromFactory() {
+ RoleValidator expectedRoleValidator = new AlwaysValidRoleValidator();
+ when(roleValidatorFactory.by(any())).thenReturn(expectedRoleValidator);
+
+ RoleValidator result = roleProvider.getUserRolesValidator(request);
+
+ assertThat(result).isEqualTo(expectedRoleValidator);
+ }
+
+ private String owningEntityId() {
+ // while translateOwningEntityNameToOwningEntityId does nothing, no translation happens.
+ // this will be changed later.
+ return SAMPLE_SUBSCRIBER;
+ }
+
private void setSubscribers() {
Subscriber subscriber = new Subscriber();
subscriber.subscriberName = SAMPLE_SUBSCRIBER;
- subscriber.globalCustomerId = SAMPLE_CUSTOMER_ID;
+ subscriber.globalCustomerId = SAMPLE_SUBSCRIBER_ID;
SubscriberList subscriberList = new SubscriberList(Lists.list(subscriber));
when(aaiService.getFullSubscriberList()).thenReturn(subscriberListResponse);
when(subscriberListResponse.getT()).thenReturn(subscriberList);
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByOwningEntityTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByOwningEntityTest.java
new file mode 100644
index 000000000..d84ac6edd
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByOwningEntityTest.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.withSettings;
+import static org.testng.Assert.assertFalse;
+
+import com.google.common.collect.ImmutableList;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class RoleValidatorByOwningEntityTest {
+
+ private static final String OWNING_ENTITY_ID = "owningEntityId";
+ private static final String SUBSCRIBER_NAME = "subscriber_name";
+ private static final String NOT_MATCHING_OWNING_ENTITY_ID = "notMatchingOwningEntityId";
+
+ private static final String SERVICE_TYPE = "serviceType";
+ private static final String GLOBAL_CUSTOMER_ID = "globalCustomerId";
+ private static final String TENANT_NAME = "tenantName";
+
+
+ private RoleValidatorByOwningEntity roleValidatorByOwningEntity;
+
+ @BeforeMethod
+ public void setup() {
+ final Role SAMPLE_ROLE = new Role(EcompRole.READ, "", "", "", OWNING_ENTITY_ID);
+ roleValidatorByOwningEntity = new RoleValidatorByOwningEntity(ImmutableList.of(SAMPLE_ROLE));
+ }
+
+ @Test
+ public void testIsSubscriberPermitted() {
+ assertFalse(roleValidatorByOwningEntity.isSubscriberPermitted(SUBSCRIBER_NAME));
+ }
+
+ @Test
+ public void isServicePermitted_owningEntityMatch_returnTrue() {
+ PermissionPropertiesOwningEntity permittedOwningEntity =
+ new PermissionPropertiesOwningEntity(OWNING_ENTITY_ID);
+
+ assertThat(roleValidatorByOwningEntity.isServicePermitted(permittedOwningEntity), is(true));
+ }
+
+ @DataProvider
+ public static Object[][] nonMatchingPermissionProperties() {
+ return new Object[][]{
+ {new PermissionPropertiesOwningEntity(NOT_MATCHING_OWNING_ENTITY_ID)},
+ {new PermissionPropertiesOwningEntity("")},
+ {new WithPermissionProperties() {}},
+ {mock(PermissionPropertiesOwningEntity.class,
+ withSettings().name("PermissionPropertiesOwningEntity with null owningEntityId"))},
+ {new PermissionPropertiesSubscriberAndServiceType(OWNING_ENTITY_ID, OWNING_ENTITY_ID)},
+ };
+ }
+
+ @Test(dataProvider = "nonMatchingPermissionProperties")
+ public void isServicePermitted_nonMatchingPermissionProperties_returnFalse(WithPermissionProperties permissionProperties) {
+ assertThat(permissionProperties.toString(), roleValidatorByOwningEntity.isServicePermitted(
+ permissionProperties
+ ), is(false));
+ }
+
+ @Test
+ public void testIsTenantPermitted() {
+ assertFalse(roleValidatorByOwningEntity.isTenantPermitted(GLOBAL_CUSTOMER_ID, SERVICE_TYPE, TENANT_NAME));
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByRolesTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByRolesTest.java
deleted file mode 100644
index 9362ec9d7..000000000
--- a/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorByRolesTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
- * 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.
- * ============LICENSE_END=========================================================
- */
-
-package org.onap.vid.roles;
-
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import java.util.List;
-import java.util.Map;
-import org.onap.vid.mso.rest.RequestDetails;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-public class RoleValidatorByRolesTest {
-
- private static final String SAMPLE_SUBSCRIBER = "sampleSubscriber";
- private static final String NOT_MATCHING_SUBSCRIBER = "notMatchingSubscriber";
- private static final String SAMPLE_SERVICE_TYPE = "sampleServiceType";
- private static final String NOT_MATCHING_TENANT = "notMatchingTenant";
- private static final String SAMPLE_TENANT = "sampleTenant";
-
- private static final Role SAMPLE_ROLE = new Role(EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT);
-
- private List<Role> roles = ImmutableList.of(SAMPLE_ROLE);
- private Map<String, Object> subscriberInfo = ImmutableMap.of("globalSubscriberId", SAMPLE_SUBSCRIBER);
- private Map<String, Object> requestParameters = ImmutableMap.of("subscriptionServiceType", SAMPLE_SERVICE_TYPE);
- private Map<String, Object> requestDetailsProperties = ImmutableMap.of("subscriberInfo", subscriberInfo, "requestParameters", requestParameters);
- private RequestDetails requestDetails;
- private RoleValidatorByRoles roleValidator;
-
- @BeforeMethod
- public void setUp() {
- roleValidator = new RoleValidatorByRoles(roles);
- requestDetails = new RequestDetails();
- }
-
- @Test
- public void shouldPermitSubscriberWhenNameMatchesAndRolesAreEnabled() {
- assertThat(roleValidator.isSubscriberPermitted(SAMPLE_SUBSCRIBER)).isTrue();
- }
-
- @Test
- public void shouldNotPermitSubscriberWhenNameNotMatches() {
- assertThat(roleValidator.isSubscriberPermitted(NOT_MATCHING_SUBSCRIBER)).isFalse();
- }
-
- @Test
- public void shouldPermitServiceWhenNamesMatches() {
- assertThat(roleValidator.isServicePermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE)).isTrue();
- }
-
-
- @Test
- public void shouldNotPermitServiceWhenSubscriberNameNotMatches() {
- assertThat(roleValidator.isServicePermitted(NOT_MATCHING_SUBSCRIBER, SAMPLE_SERVICE_TYPE)).isFalse();
- }
-
- @Test
- public void shouldNotPermitServiceWhenServiceTypeNotMatches() {
- assertThat(roleValidator.isServicePermitted(SAMPLE_SUBSCRIBER, NOT_MATCHING_SUBSCRIBER)).isFalse();
- }
-
- @Test
- public void shouldPermitTenantWhenNameMatches() {
- assertThat(roleValidator.isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT)).isTrue();
- }
-
-
- @Test
- public void shouldNotPermitTenantWhenNameNotMatches() {
- assertThat(roleValidator.isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, NOT_MATCHING_TENANT)).isFalse();
- }
-
- @Test
- public void shouldValidateProperlySORequest() {
- requestDetails.setAdditionalProperty("requestDetails", requestDetailsProperties);
-
- assertThat(roleValidator.isMsoRequestValid(requestDetails)).isTrue();
- }
-
- @Test
- public void shouldValidateUnknownSORequest() {
- assertThat(roleValidator.isMsoRequestValid(new RequestDetails())).isTrue();
- }
-
- @Test
- public void shouldRejectSORequestWhenSubscriberNotMatches() {
- Map<String, Object> subscriberInfo = ImmutableMap.of("globalSubscriberId", "sample");
- Map<String, Object> requestDetailsProperties = ImmutableMap.of("subscriberInfo", subscriberInfo, "requestParameters", requestParameters);
- requestDetails.setAdditionalProperty("requestDetails", requestDetailsProperties);
-
- assertThat(roleValidator.isMsoRequestValid(requestDetails)).isFalse();
- }
-}
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceTypeTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceTypeTest.java
new file mode 100644
index 000000000..b6958cd67
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorBySubscriberAndServiceTypeTest.java
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class RoleValidatorBySubscriberAndServiceTypeTest {
+
+ private static final String SAMPLE_SUBSCRIBER = "sampleSubscriber";
+ private static final String NOT_MATCHING_SUBSCRIBER = "notMatchingSubscriber";
+ private static final String SAMPLE_SERVICE_TYPE = "sampleServiceType";
+ private static final String NOT_MATCHING_TENANT = "notMatchingTenant";
+ private static final String SAMPLE_TENANT = "sampleTenant";
+ private static final String SOME_OWNING_ENTITY_ID = "someOwningEntityId";
+
+ private static final Role SAMPLE_ROLE = new Role(
+ EcompRole.READ, SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT, SOME_OWNING_ENTITY_ID);
+
+ private List<Role> roles = ImmutableList.of(SAMPLE_ROLE);
+ private RoleValidatorBySubscriberAndServiceType roleValidatorBySubscriberAndServiceType;
+
+ @BeforeMethod
+ public void setUp() {
+ roleValidatorBySubscriberAndServiceType = new RoleValidatorBySubscriberAndServiceType(roles);
+ }
+
+ @Test
+ public void shouldPermitSubscriberWhenNameMatchesAndRolesAreEnabled() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isSubscriberPermitted(SAMPLE_SUBSCRIBER)).isTrue();
+ }
+
+ @Test
+ public void shouldNotPermitSubscriberWhenNameNotMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isSubscriberPermitted(NOT_MATCHING_SUBSCRIBER)).isFalse();
+ }
+
+ @Test
+ public void shouldPermitServiceWhenNamesMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE))).isTrue();
+ }
+
+ @Test
+ public void isServicePermitted_serviceWithAllPermissionProperties_isPermitted() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new AllPermissionProperties(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SOME_OWNING_ENTITY_ID))).isTrue();
+ }
+
+ @Test
+ public void shouldNotPermitServiceWhenSubscriberNameNotMatches() {
+ assertThat(
+ roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(NOT_MATCHING_SUBSCRIBER, SAMPLE_SERVICE_TYPE))).isFalse();
+ }
+
+ @Test
+ public void shouldNotPermitServiceWhenServiceTypeNotMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesSubscriberAndServiceType(SAMPLE_SUBSCRIBER, NOT_MATCHING_SUBSCRIBER))).isFalse();
+ }
+
+ @Test
+ public void isServicePermitted_owningEntityPermissionProperties_isNotPermitted() {
+ assertThat(roleValidatorBySubscriberAndServiceType.isServicePermitted(
+ new PermissionPropertiesOwningEntity(SAMPLE_SUBSCRIBER))).isFalse();
+ }
+
+ @Test
+ public void shouldPermitTenantWhenNameMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType
+ .isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT)).isTrue();
+ }
+
+ @Test
+ public void shouldPermitTenantWhenNameMatchesCaseInsensitive() {
+ assertThat(roleValidatorBySubscriberAndServiceType
+ .isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, SAMPLE_TENANT.toUpperCase())).isTrue();
+ }
+
+
+ @Test
+ public void shouldNotPermitTenantWhenNameNotMatches() {
+ assertThat(roleValidatorBySubscriberAndServiceType
+ .isTenantPermitted(SAMPLE_SUBSCRIBER, SAMPLE_SERVICE_TYPE, NOT_MATCHING_TENANT)).isFalse();
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorFactoryTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorFactoryTest.java
new file mode 100644
index 000000000..b3c71c547
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorFactoryTest.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+import static java.util.Collections.emptyList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.List;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.onap.vid.properties.Features;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.togglz.core.manager.FeatureManager;
+
+public class RoleValidatorFactoryTest {
+
+ @InjectMocks
+ private RoleValidatorFactory roleValidatorFactory;
+
+ @Mock
+ private FeatureManager featureManager;
+
+ @BeforeClass
+ public void initMocks() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @AfterMethod
+ public void reset() {
+ Mockito.reset(featureManager);
+ }
+
+ @Test (dataProvider = "presetRoleValidatorClass")
+ public void returnRoleValidatorByGivenClass_And_RoleManagementActivated_And_FeatureFlag(Class expectedClass,boolean isDisabledRoles, boolean flagActive ) {
+
+ when(featureManager.isActive(Features.FLAG_2006_USER_PERMISSIONS_BY_OWNING_ENTITY)).thenReturn(flagActive);
+ RoleValidator roleValidator = roleValidatorFactory.by(emptyList(), isDisabledRoles);
+ assertThat(roleValidator, instanceOf(expectedClass));
+ }
+
+ @DataProvider
+ public static Object[][] presetRoleValidatorClass() {
+ return new Object[][] {
+ {RoleValidatorsComposer.class, false, true},
+ {AlwaysValidRoleValidator.class, true, true},
+ {RoleValidatorBySubscriberAndServiceType.class, false, false},
+ {AlwaysValidRoleValidator.class, true, false}
+ };
+ }
+
+} \ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorsComposerTest.java b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorsComposerTest.java
new file mode 100644
index 000000000..c0892dafb
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/roles/RoleValidatorsComposerTest.java
@@ -0,0 +1,110 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 - 2020 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.vid.roles;
+
+import static java.util.stream.Collectors.toList;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.withSettings;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.function.Function;
+import java.util.stream.Stream;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class RoleValidatorsComposerTest {
+
+ private RoleValidator alwaysTrueRoles;
+ private RoleValidator alwaysFalseRoles;
+
+ @DataProvider
+ public static Object[][] allInterfaceFunctions() {
+ return Stream.<Function<RoleValidator, Boolean>>of(
+ (RoleValidator o) -> o.isSubscriberPermitted("subscriberId"),
+ (RoleValidator o) -> o.isServicePermitted(new WithPermissionProperties() {}),
+ (RoleValidator o) -> o.isTenantPermitted("subscriberId", "serviceType", "tenantName")
+ ).map(it -> new Object[]{it}).collect(toList()).toArray(new Object[][]{});
+ }
+
+ @BeforeMethod
+ public void setUp() {
+ alwaysTrueRoles = mock(RoleValidator.class, withSettings().defaultAnswer(o -> true));
+ alwaysFalseRoles = mock(RoleValidator.class);
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void emptyComposite_returnsFalse(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer();
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(false)
+ );
+
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void falseAndTrueComposite_returnsTrue(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest =
+ new RoleValidatorsComposer(alwaysFalseRoles, alwaysFalseRoles, alwaysTrueRoles);
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(true)
+ );
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void trueAndFalseComposite_returnsTrueAndShortCircuits(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer(alwaysTrueRoles, alwaysFalseRoles);
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(true)
+ );
+
+ verifyZeroInteractions(alwaysFalseRoles);
+ }
+
+ @Test(dataProvider = "allInterfaceFunctions")
+ public void falseAndFalseComposite_returnsFalse(Function<RoleValidator, Boolean> interfaceFunction) {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer(alwaysFalseRoles, alwaysFalseRoles);
+
+ assertThat(
+ interfaceFunction.apply(underTest),
+ is(false)
+ );
+ }
+
+ @Test
+ public void secondaryConstructor_givenSetIfValidators_returnsTrue() {
+ RoleValidatorsComposer underTest = new RoleValidatorsComposer(
+ ImmutableSet.of(alwaysTrueRoles)
+ );
+
+ assertThat(underTest.isSubscriberPermitted("anything"), is(true));
+ }
+
+}
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/AAITreeNodeBuilderTest.java b/vid-app-common/src/test/java/org/onap/vid/services/AAITreeNodeBuilderTest.java
index 29041839a..67d3d4a9a 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/AAITreeNodeBuilderTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/AAITreeNodeBuilderTest.java
@@ -50,7 +50,10 @@ import java.util.Optional;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.mockito.Mock;
import org.mockito.stubbing.Answer;
@@ -79,6 +82,7 @@ public class AAITreeNodeBuilderTest {
private ExecutorService executorService;
private Logging logging = new Logging();
+ private static final Logger logger = LogManager.getLogger(AAITreeNodeBuilderTest.class);
private static final ObjectMapper mapper = new ObjectMapper();
@@ -92,7 +96,9 @@ public class AAITreeNodeBuilderTest {
private void buildNodeAndAssert(JsonNode inputNode, AAITreeNode expectedNode, NodeType nodeType){
ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
when(aaiClientMock.typedAaiRest(Unchecked.toURI("anyUrl"), JsonNode.class, null, HttpMethod.GET, false)).thenReturn(inputNode);
- AAITreeNode actualNode = aaiTreeNodeBuilder.buildNode(
+ AAITreeNode actualNode;
+ try {
+ actualNode = aaiTreeNodeBuilder.buildNode(
nodeType,
"anyUrl",
null,
@@ -100,7 +106,16 @@ public class AAITreeNodeBuilderTest {
nodesAccumulator,
executorService,
AAI_TREE_PATHS.getSubTree(new AAIServiceTree.AaiRelationship(nodeType))
- ).get(0);
+ ).get(0);
+ } catch (Throwable e) {
+ //print stack traces for more information in case of failure
+ System.out.println("Failed to build node by aaiTreeNodeBuilder");
+ ExceptionUtils.getThrowableList(e)
+ .stream()
+ .peek(it ->System.err.println(it.getLocalizedMessage()))
+ .forEach(Throwable::printStackTrace);
+ throw e;
+ }
assertThat(actualNode, jsonEquals(expectedNode).when(IGNORING_ARRAY_ORDER, IGNORING_EXTRA_FIELDS).whenIgnoringPaths("relationshipList","children[0].relationshipList"));
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceImplTest.java b/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceImplTest.java
index d3b2a48b1..a37482624 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceImplTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceImplTest.java
@@ -183,7 +183,7 @@ public class AaiServiceImplTest {
AaiResponse<Services> aaiResponseServices = new AaiResponse<>(services, null, HttpStatus.SC_OK);
when(aaiClient.getSubscriberData(SUBSCRIBER_ID, false)).thenReturn(aaiResponseServices);
- when(roleValidator.isServicePermitted(eq(GLOBAL_CUSTOMER_ID), anyString())).thenReturn(Boolean.TRUE);
+ when(roleValidator.isServicePermitted(any())).thenReturn(Boolean.TRUE);
AaiResponse actualResponse = aaiService.getSubscriberData(SUBSCRIBER_ID, roleValidator, false);
List<ServiceSubscription> actualServiceSubscriptions = ((AaiResponse<Services>) actualResponse)
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceTest.java b/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceTest.java
index 6aa67051e..4d6566f5b 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/AaiServiceTest.java
@@ -20,35 +20,53 @@
package org.onap.vid.services;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
+import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayWithSize;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.nullValue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
+import org.jetbrains.annotations.NotNull;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.onap.vid.aai.AaiClientInterface;
import org.onap.vid.aai.AaiResponse;
+import org.onap.vid.aai.ServiceInstance;
import org.onap.vid.aai.model.AaiGetPnfResponse;
import org.onap.vid.aai.model.AaiGetPnfs.Pnf;
import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.onap.vid.aai.model.LogicalLinkResponse;
+import org.onap.vid.aai.model.OwningEntityResponse;
+import org.onap.vid.aai.model.ProjectResponse;
import org.onap.vid.aai.model.Relationship;
import org.onap.vid.aai.model.RelationshipData;
import org.onap.vid.aai.model.RelationshipList;
import org.onap.vid.aai.model.ServiceRelationships;
+import org.onap.vid.model.ServiceInstanceSearchResult;
import org.onap.vid.model.aaiTree.AAITreeNode;
-import org.onap.vid.roles.Role;
import org.onap.vid.roles.RoleValidator;
+import org.onap.vid.roles.RoleValidatorFactory;
+import org.onap.vid.roles.WithPermissionProperties;
+import org.onap.vid.testUtils.TestUtils;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -61,6 +79,9 @@ public class AaiServiceTest {
@Mock
private AaiClientInterface aaiClientInterface;
+ @Mock
+ private RoleValidatorFactory roleValidatorFactory;
+
@BeforeMethod
public void initMocks(){
MockitoAnnotations.initMocks(this);
@@ -68,7 +89,7 @@ public class AaiServiceTest {
@Test
public void testGetSpecificPnf(){
- Pnf pnf = new Pnf("11111", null, null, null, null, null, null);
+ Pnf pnf = Pnf.builder().withPnfId("11111").build();
AaiResponse<Pnf> aaiResponse = new AaiResponse<>(pnf, "aaaa", 200);
Mockito.doReturn(aaiResponse).when(aaiClientInterface).getSpecificPnf(Mockito.anyString());
AaiResponse<Pnf> specificPnf = aaiService.getSpecificPnf("1345667");
@@ -150,8 +171,6 @@ public class AaiServiceTest {
public static Object[][] getTenantsData() {
return new Object[][] {
{"customer1", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TeNant1", "customer1", "serviceType1", "tenant1", "id-1", true},
- {"customer1", "serviceType1", "TENANT1", "customer1", "serviceType1", "tenant1", "id-1", true},
{"customer1", "serviceType1", "tenant2", "customer1", "serviceType1", "tenant1", "tenant2", false},
{"customer1", "serviceType1", null, "customer1", "serviceType1", "tenant1", "tenant2", true},
{"customer2", "serviceType1", "tenant1", "customer1", "serviceType1", "tenant1", "id-1", false},
@@ -162,14 +181,20 @@ public class AaiServiceTest {
}
@Test(dataProvider = "getTenantsData")
- public void testGetTenants(String userGlobalCustomerId, String userServiceType, String userTenantName, String serviceGlobalCustomerId,
- String serviceServiceType, String serviceTenantName, String serviceTenantId, boolean expectedIsPermitted) {
+ public void testGetTenants(String userGlobalCustomerId, String userServiceType, String userTenantName,
+ String serviceGlobalCustomerId, String serviceServiceType, String serviceTenantName,
+ String serviceTenantId, boolean expectedIsPermitted) {
GetTenantsResponse[] getTenantsResponses = new GetTenantsResponse[] {new GetTenantsResponse(null, null, serviceTenantName, serviceTenantId, false)};
AaiResponse<GetTenantsResponse[]> aaiResponse = new AaiResponse<>(getTenantsResponses, null, 200);
Mockito.doReturn(aaiResponse).when(aaiClientInterface).getTenants(serviceGlobalCustomerId, serviceServiceType);
- Role role = new Role(null, userGlobalCustomerId, userServiceType, userTenantName);
- RoleValidator roleValidator = RoleValidator.by(Collections.singletonList(role), false);
- AaiResponse<GetTenantsResponse[]> actualTenants = aaiService.getTenants(serviceGlobalCustomerId, serviceServiceType, roleValidator);
+
+ RoleValidator roleValidatorMock = mock(RoleValidator.class);
+ when(roleValidatorMock.isTenantPermitted(
+ eq(userGlobalCustomerId), eq(userServiceType),
+ (userTenantName == null) ? anyString() : eq(userTenantName))
+ ).thenReturn(true);
+
+ AaiResponse<GetTenantsResponse[]> actualTenants = aaiService.getTenants(serviceGlobalCustomerId, serviceServiceType, roleValidatorMock);
assertThat(actualTenants.getT(), arrayWithSize(1));
assertThat(actualTenants.getT()[0].tenantName, equalTo(serviceTenantName));
@@ -206,4 +231,112 @@ public class AaiServiceTest {
assertThat(anyMatch, equalTo(expectedMatch));
}
+ @DataProvider
+ public static Object[][] dataToDestroy() {
+ return new Object[][]{
+ {"nothing"}, {"relationship-list"}, {"relationship"}, {"relationship-data"} ,{"owning-entity-id"}
+ };
+ }
+
+
+ @Test(dataProvider = "dataToDestroy")
+ public void relatedOwningEntityId_givenInstanceAndOptionalError_extractCorrectlyOrReturnNull(String dataToDestroy) throws JsonProcessingException {
+ ServiceInstance serviceInstance = new ObjectMapper().readValue((""
+ + "{ "
+ + " \"service-instance-id\": \"5d521981-33be-4bb5-bb20-5616a9c52a5a\", "
+ + " \"service-instance-name\": \"dfgh\", "
+ + " \"service-type\": \"\", "
+ + " \"service-role\": \"\", "
+ + " \"environment-context\": \"null\", "
+ + " \"workload-context\": \"null\", "
+ + " \"model-invariant-id\": \"331a194d-9248-4533-88bc-62c812ccb5c1\", "
+ + " \"model-version-id\": \"171b3887-e73e-479d-8ef8-2690bf74f2aa\", "
+ + " \"resource-version\": \"1508832105498\", "
+ + " \"orchestration-status\": \"Active\", "
+ + " \"relationship-list\": { "
+ + " \"relationship\": [ "
+ + " { "
+ + " \"related-to\": \"project\", "
+ + " \"related-link\": \"/aai/v11/business/projects/project/Kennedy\", "
+ + " \"relationship-data\": [ "
+ + " { "
+ + " \"relationship-key\": \"project.project-name\", "
+ + " \"relationship-value\": \"Kennedy\" "
+ + " } "
+ + " ] "
+ + " }, "
+ + " { "
+ + " \"related-to\": \"owning-entity\", "
+ + " \"related-link\": \"/aai/v11/business/owning-entities/owning-entity/4d4ecf59-41f1-40d4-818d-885234680a42\", "
+ + " \"relationship-data\": [ "
+ + " { "
+ + " \"relationship-key\": \"owning-entity.owning-entity-id\", "
+ + " \"relationship-value\": \"4d4ecf59-41f1-40d4-818d-885234680a42\" "
+ + " } "
+ + " ] "
+ + " } "
+ + " ] "
+ + " } "
+ + "}").replace(dataToDestroy, "omitted"), ServiceInstance.class);
+
+ if (dataToDestroy.equals("nothing")) {
+ assertThat(aaiService.relatedOwningEntityId(serviceInstance), is("4d4ecf59-41f1-40d4-818d-885234680a42"));
+ } else {
+ assertThat(aaiService.relatedOwningEntityId(serviceInstance), is(nullValue()));
+ }
+ }
+
+ @Test
+ public void testGetServicesByOwningEntityId() {
+
+ //given
+ List<String> owningEntityIds = ImmutableList.of("43b8a85a-0421-4265-9069-117dd6526b8a", "26dcc4aa-725a-447d-8346-aa26dfaa4eb7");
+ OwningEntityResponse owningEntityResponse = TestUtils.readJsonResourceFileAsObject("/responses/aai/listServicesByOwningEntity.json", OwningEntityResponse.class);
+ when(aaiClientInterface.getServicesByOwningEntityId(owningEntityIds)).thenReturn(new AaiResponse<>(owningEntityResponse, "", 200));
+ RoleValidator roleValidator = createAlwaysTrueRoleValidator();
+
+ //when
+ List<ServiceInstanceSearchResult> result = aaiService.getServicesByOwningEntityId(owningEntityIds, roleValidator);
+
+ //then
+ ServiceInstanceSearchResult expected1 = new ServiceInstanceSearchResult(
+ "af9d52f9-13b2-4657-a198-463677f82dc0", "256cddb4-3aa1-43cc-a08f-315bb50b275e", "MSO-dev-service-type", "xbghrftgr_shani", null, null, null, "43b8a85a-0421-4265-9069-117dd6526b8a", true);
+ ServiceInstanceSearchResult expected2 = new ServiceInstanceSearchResult(
+ "49769492-5def-4c89-8e73-b236f958fa40", "e02fd6f2-7fc2-434b-a92d-15abdb24b68d", "JUST-another-service-type", "fghghfhgf", null, null, null, "43b8a85a-0421-4265-9069-117dd6526b8a", true);
+ ServiceInstanceSearchResult expected3 = new ServiceInstanceSearchResult(
+ "1d8fd482-2f53-4d62-a7bd-20e4bab14c45", "256cddb4-3aa1-43cc-a08f-315bb50b275e", "MSO-dev-service-type", "Bryant", null, null, null, "26dcc4aa-725a-447d-8346-aa26dfaa4eb7", true);
+
+ assertThat(result, jsonEquals(ImmutableList.of(expected1, expected2, expected3)).when(IGNORING_ARRAY_ORDER).whenIgnoringPaths("[*].subscriberName")); //ignore in array
+ }
+
+ @NotNull
+ private RoleValidator createAlwaysTrueRoleValidator() {
+ RoleValidator roleValidator = mock(RoleValidator.class);
+ when(roleValidator.isServicePermitted(any(WithPermissionProperties.class))).thenReturn(true);
+ return roleValidator;
+ }
+
+ @Test
+ public void testGetServicesByProjectNames() {
+
+ //given
+ List<String> projectNames = ImmutableList.of("x1", "y2");
+ ProjectResponse projectResponse = TestUtils.readJsonResourceFileAsObject("/responses/aai/listServicesByProject.json", ProjectResponse.class);
+ when(aaiClientInterface.getServicesByProjectNames(projectNames)).thenReturn(new AaiResponse<>(projectResponse, "", 200));
+ RoleValidator roleValidator = createAlwaysTrueRoleValidator();
+
+ //when
+ List<ServiceInstanceSearchResult> result = aaiService.getServicesByProjectNames(projectNames, roleValidator);
+
+ //then
+ ServiceInstanceSearchResult expected1 = new ServiceInstanceSearchResult(
+ "3f826016-3ac9-4928-9561-beee75fd91d5", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", "Emanuel", "Lital_SRIOV2_001", null, null, null, null, true);
+ ServiceInstanceSearchResult expected2 = new ServiceInstanceSearchResult(
+ "7e4f8130-5dee-47c4-8770-1abc5f5ded83", "3d15d7ea-4174-49b6-89ec-e569381f7231", "vMOG", "justAname", null, null, null, null, true);
+ ServiceInstanceSearchResult expected3 = new ServiceInstanceSearchResult(
+ "ff2d9326-1ef5-4760-aba0-0eaf372ae675", "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", "Yoda", "anotherName", null, null, null, null, true);
+
+ assertThat(result, jsonEquals(ImmutableList.of(expected1, expected2, expected3)).when(IGNORING_ARRAY_ORDER).whenIgnoringPaths("[*].subscriberName")); //ignore in array
+ }
+
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBaseTest.java b/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBaseTest.java
index b9535000a..f61131770 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBaseTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBaseTest.java
@@ -22,7 +22,6 @@ package org.onap.vid.services;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
-import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
@@ -65,6 +64,7 @@ import org.onap.vid.model.serviceInstantiation.VfModule;
import org.onap.vid.model.serviceInstantiation.Vnf;
import org.onap.vid.mso.RestObject;
import org.onap.vid.mso.model.ModelInfo;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
import org.onap.vid.mso.rest.AsyncRequestStatus;
import org.onap.vid.mso.rest.RequestStatus;
import org.onap.vid.properties.Features;
@@ -237,7 +237,7 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
testApi,
instanceId,
action.name(),
- UUID.randomUUID().toString(), null, null, null);
+ UUID.randomUUID().toString(), null, null, null, null);
}
private List<Map<String,String>> createInstanceParams() {
@@ -249,8 +249,10 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
return instanceParams;
}
- protected VfModule createVfModule(String modelName, String modelVersionId, String modelCustomizationId,
- List<Map<String, String>> instanceParams, Map<String, String> supplementaryParams, String instanceName, String volumeGroupInstanceName, boolean isAlacarte) {
+ protected VfModule createVfModule(
+ String modelName, String modelVersionId, String modelCustomizationId,
+ List<Map<String, String>> instanceParams, List<UserParamNameAndValue> supplementaryParams, String instanceName,
+ String volumeGroupInstanceName, boolean isAlacarte, Boolean usePreload) {
ModelInfo vfModuleInfo = new ModelInfo();
vfModuleInfo.setModelType("vfModule");
vfModuleInfo.setModelName(modelName);
@@ -262,13 +264,14 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
vfModuleInfo.setModelInvariantId("22222222-f63c-463e-ba94-286933b895f9");
vfModuleInfo.setModelVersion("10.0");
return new VfModule(vfModuleInfo, instanceName, volumeGroupInstanceName, Action.Create.name(), "mdt1", null,
- "88a6ca3ee0394ade9403f075db23167e", instanceParams, supplementaryParams, false, true, null, UUID.randomUUID().toString(), null, null,
- null, null, null);
+ "88a6ca3ee0394ade9403f075db23167e", instanceParams, supplementaryParams, false,
+ usePreload, null, UUID.randomUUID().toString(), null, null,
+ null, null, null, "originalName");
}
return new VfModule(vfModuleInfo, instanceName, volumeGroupInstanceName, Action.Create.name(), null, null, null,
instanceParams, supplementaryParams, false, false, null, UUID.randomUUID().toString(), null,
- null, null, null, null);
+ null, null, null, null, "originalName");
}
protected ModelInfo createVfModuleModelInfo(String modelName, String modelVersion, String modelVersionId, String modelInvariantId, String modelCustomizationId, String modelCustomizationName) {
@@ -276,9 +279,9 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
}
protected VfModule createVfModuleForReplace(ModelInfo vfModuleModelInfo, String instanceName,
- String lcpCloudRegionId, String tenantId, Boolean retainAssignments, Boolean retainVolumeGroups, Map<String, String> supplementaryParams) {
+ String lcpCloudRegionId, String tenantId, Boolean retainAssignments, Boolean retainVolumeGroups, List<UserParamNameAndValue> supplementaryParams) {
return new VfModule( vfModuleModelInfo, instanceName, null, Action.Upgrade.name(), lcpCloudRegionId, null, tenantId,
- null, supplementaryParams, true, null, null, UUID.randomUUID().toString(), null, null, retainAssignments, retainVolumeGroups, null);
+ null, supplementaryParams, true, null, null, UUID.randomUUID().toString(), null, null, retainAssignments, retainVolumeGroups, null, "originalName");
}
protected ModelInfo createVnfModelInfo(boolean isAlacarte) {
@@ -349,9 +352,11 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
Map<String, Map<String, VfModule>> vfModules = new HashMap<>();
List<Map<String, String>> instanceParams1 = ImmutableList.of((ImmutableMap.of("vmx_int_net_len", "24")));
- VfModule vfModule1 = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME, instanceParams1, new HashMap<>(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vPE_BV_base" : null), null, isAlacarte);
+ VfModule vfModule1 = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME,
+ instanceParams1, emptyList(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vPE_BV_base" : null), null, isAlacarte, true);
List<Map<String, String>> instanceParams2 = ImmutableList.of(vfModuleInstanceParamsMap);
- VfModule vfModule2 = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1", VF_MODULE_1_MODEL_VERSION_ID, VF_MODULE_1_MODEL_CUSTOMIZATION_NAME, instanceParams2, new HashMap<>(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion": null), (isUserProvidedNaming ? "myVgName" : null), isAlacarte);
+ VfModule vfModule2 = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1", VF_MODULE_1_MODEL_VERSION_ID, VF_MODULE_1_MODEL_CUSTOMIZATION_NAME,
+ instanceParams2, emptyList(), (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion": null), (isUserProvidedNaming ? "myVgName" : null), isAlacarte, true);
String vfModuleModelName = vfModule1.getModelInfo().getModelName();
vfModules.put(vfModuleModelName, new LinkedHashMap<>());
@@ -361,7 +366,7 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
Vnf vnf = new Vnf(vnfModelInfo, "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", (isUserProvidedNaming ? VNF_NAME : null), Action.Create.name(),
"platformName", "mdt1", null, "88a6ca3ee0394ade9403f075db23167e", vnfInstanceParams,"lineOfBusinessName" , false, null, vfModules,
- UUID.randomUUID().toString(), null, null, null);
+ UUID.randomUUID().toString(), null, null, null, "originalName");
vnfs.put(vnf.getModelInfo().getModelName(), vnf);
return vnfs;
@@ -393,7 +398,7 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", null, "MOG", lcpCloudRegionId, null, tenantId,
null, null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, instanceParams, false, 1, false, false,
null, null, null, null, null, null,
- new VidNotions(InstantiationUI.TRANSPORT_SERVICE, ModelCategory.Transport, InstantiationUI.TRANSPORT_SERVICE, InstantiationType.Macro)
+ new VidNotions(InstantiationUI.TRANSPORT_SERVICE, ModelCategory.Transport, InstantiationUI.TRANSPORT_SERVICE, InstantiationType.Macro), "originalName"
);
return serviceInstantiation;
}
@@ -414,7 +419,7 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
details->new Network(createNetworkModelInfo(isALaCarte, details.modelCustomizationId), "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb",
details.name, Action.Create.name(),
"platformName", "mdt1", null, "88a6ca3ee0394ade9403f075db23167e", instanceParams,"lineOfBusinessName" ,
- false, null, UUID.randomUUID().toString(), null, null, null));
+ false, null, UUID.randomUUID().toString(), null, null, null, "originalName"));
// I can't tell why compiler don't like the statement if it's only one line...
return networkStream.collect(Collectors.toMap(network -> network.getModelInfo().getModelCustomizationId(), network -> network));
}
@@ -430,7 +435,7 @@ public class AsyncInstantiationBaseTest extends AbstractTestNGSpringContextTests
modelInfo.setModelVersion("10.0");
return new InstanceGroup(modelInfo, (isUserProvidedNaming ? VNF_GROUP_NAME : null), action.name(), false, null, emptyMap(), UUID.randomUUID().toString(), null, null,
- null);
+ null, "originalName");
}
protected ModelInfo createServiceModelInfo() {
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBusinessLogicTest.java b/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBusinessLogicTest.java
index 7a6b94a1a..284efce45 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBusinessLogicTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/AsyncInstantiationBusinessLogicTest.java
@@ -23,8 +23,10 @@ package org.onap.vid.services;
import static net.javacrumbs.jsonunit.JsonAssert.assertJsonEquals;
import static net.javacrumbs.jsonunit.JsonAssert.whenIgnoringPaths;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItem;
@@ -59,12 +61,14 @@ import static org.onap.vid.job.Job.JobStatus.PAUSE;
import static org.onap.vid.job.Job.JobStatus.PENDING;
import static org.onap.vid.job.Job.JobStatus.STOPPED;
import static org.onap.vid.testUtils.TestUtils.generateRandomAlphaNumeric;
+import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
+import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -150,8 +154,6 @@ import org.testng.annotations.Test;
@ContextConfiguration(classes = {DataSourceConfig.class, SystemProperties.class, MockedAaiClientAndFeatureManagerConfig.class})
public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseTest {
-
-
@Mock
private JobAdapter jobAdapterMock;
@@ -1054,7 +1056,7 @@ public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseT
public void whenLcpRegionNotEmpty_thenCloudRegionIdOfResourceIsLegacy() {
String legacyCloudRegion = "legacyCloudRegion";
Vnf vnf = new Vnf(new ModelInfo(), null, null, Action.Create.name(), null, "anyCloudRegion", legacyCloudRegion,
- null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null);
+ null, null, null, false, null, null, UUID.randomUUID().toString(), null, null, null, "originalName");
assertThat(vnf.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
}
@@ -1063,7 +1065,7 @@ public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseT
String legacyCloudRegion = "legacyCloudRegion";
ServiceInstantiation service = new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
null, null, "anyCloudRegion", legacyCloudRegion, null, null, null, null, null, null, null, null, null,
- false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null);
+ false, 1,false, false, null, null, Action.Create.name(), UUID.randomUUID().toString(), null, null, null, "originalName");
assertThat(service.getLcpCloudRegionId(), equalTo(legacyCloudRegion));
}
@@ -1087,7 +1089,7 @@ public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseT
return new ServiceInstantiation(new ModelInfo(), null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null, null,
false, 1, false, isALaCarte, null, null, action.name(),
- UUID.randomUUID().toString(), null, null, null);
+ UUID.randomUUID().toString(), null, null, null, "originalName");
}
@DataProvider
@@ -1221,7 +1223,8 @@ public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseT
String message = "Failed to create service instance";
return new Object[][]{
{500, message},
- {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"}
+ {400, "{\"requestError\":{\"serviceException\":{\"messageId\":\"SVC0002\",\"text\":\"" + message + "\"}}}"},
+ {199, "{\"serviceException\":{\"messageId\":\"SVC2000\",\"text\":\"Error: " + message + "\"}}"},
};
}
@@ -1391,7 +1394,36 @@ public class AsyncInstantiationBusinessLogicTest extends AsyncInstantiationBaseT
{
String path = asyncInstantiationBL.getVfModuleReplacePath("myService", "myVNF", "myVFModule");
assertThat(path, equalTo("/serviceInstantiation/v7/serviceInstances/myService/vnfs/myVNF/vfModules/myVFModule/replace"));
+ }
+ @Test
+ public void whenCallClearStatusFromRequest_isFailedAndStatusAreRemoved() throws JsonProcessingException {
+ ServiceInstantiation serviceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
+ "{"
+ + " \"modelInfo\": {"
+ + " \"modelType\": \"service\""
+ + " },"
+ + " \"isFailed\": true,"
+ + " \"statusMessage\": \"some status\","
+ + " \"vnfs\": {"
+ + " \"vProbe_NC_VNF\": {"
+ + " \"modelInfo\": {"
+ + " \"modelType\": \"vnf\""
+ + " },"
+ + " \"isFailed\": true,"
+ + " \"statusMessage\": \"other status\""
+ + " }"
+ + " }"
+ + "}",
+ ServiceInstantiation.class);
+ asyncInstantiationBL.clearStatusFromRequest(serviceInstantiation);
+ assertThat(serviceInstantiation, allOf(
+ jsonPartEquals("isFailed", false),
+ jsonPartEquals("statusMessage", null),
+ jsonPartEquals("vnfs.vProbe_NC_VNF.isFailed", false),
+ jsonPartEquals("vnfs.vProbe_NC_VNF.statusMessage", null)
+ ));
}
+
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/InstantiationTemplatesServiceTest.java b/vid-app-common/src/test/java/org/onap/vid/services/InstantiationTemplatesServiceTest.java
index f09ea313c..de9fc2bcb 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/InstantiationTemplatesServiceTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/InstantiationTemplatesServiceTest.java
@@ -20,30 +20,45 @@
package org.onap.vid.services;
+import static java.lang.Boolean.FALSE;
+import static java.lang.Boolean.TRUE;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
+import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anEmptyMap;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasProperty;
+import static org.hamcrest.Matchers.nullValue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import org.mockito.InjectMocks;
import org.mockito.Mock;
+import org.onap.vid.asdc.beans.Service;
import org.onap.vid.dal.AsyncInstantiationRepository;
import org.onap.vid.model.ModelUtil;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
import org.onap.vid.model.serviceInstantiation.ServiceInstantiationTemplate;
import org.onap.vid.model.serviceInstantiation.Vnf;
+import org.onap.vid.properties.Features;
import org.onap.vid.testUtils.TestUtils;
+import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import org.togglz.core.manager.FeatureManager;
public class InstantiationTemplatesServiceTest {
@@ -53,6 +68,9 @@ public class InstantiationTemplatesServiceTest {
@Mock
private ModelUtil modelUtil;
+ @Mock
+ private FeatureManager featureManager;
+
@InjectMocks
private InstantiationTemplatesService instantiationTemplatesService;
@@ -61,6 +79,11 @@ public class InstantiationTemplatesServiceTest {
TestUtils.initMockitoMocks(this);
}
+ @AfterMethod
+ public void resetMocks() {
+ reset(featureManager);
+ }
+
@Test
public void getJobRequestAsTemplate_whenIsCalled_asyncInstantiationRepositoryGetJobRequestIsInvoked() {
UUID jobId = UUID.randomUUID();
@@ -99,4 +122,49 @@ public class InstantiationTemplatesServiceTest {
assertThat(result, hasProperty("existingVRFCounterMap", anEmptyMap()));
}
+ @DataProvider
+ public static Object[][] isTemplatesExistsByGivenServiceUuid() {
+ return new Object[][]{{"1",TRUE},
+ {"3",FALSE}};
+ }
+
+ @Test(dataProvider = "isTemplatesExistsByGivenServiceUuid")
+ public void setInServicesTemplateValue_givenServiceWithServiceModelId_thenIsTemplateExistsIsEatherTrueOrFalse(String givenUuid, Boolean expectedTemplatesExist){
+
+ Service service = new Service();
+ service.setUuid(givenUuid);
+
+ Service newService = instantiationTemplatesService.setTemplateExistForService(service, ImmutableSet.of("1", "2"));
+ assertThat(newService.getIsInstantiationTemplateExists(), is(expectedTemplatesExist));
+ }
+
+ @Test
+ public void setTemplatesExistance_givenCollection__flagIsActive_thenSameCollectionReturnedWithTemplateExistsProperty(){
+ when(featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)).thenReturn(true);
+ when(asyncInstantiationRepository.getAllTemplatesServiceModelIds()).thenReturn(ImmutableSet.of("1", "2"));
+ Collection<Service> actualCollection = instantiationTemplatesService.setOnEachServiceIsTemplateExists(createGivenCollection());
+ assertThat(actualCollection, containsInAnyOrder(
+ allOf(hasProperty("uuid", is("1")), hasProperty("isInstantiationTemplateExists", is(true))),
+ allOf(hasProperty("uuid", is("3")), hasProperty("isInstantiationTemplateExists", is(false)))
+ ));
+ }
+
+ @Test
+ public void setTemplatesExistance_givenCollection_flagIsNotActive_thenTemplatesExistNotAdded(){
+ when(featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)).thenReturn(false);
+ Collection<Service> actualCollection = instantiationTemplatesService.setOnEachServiceIsTemplateExists(createGivenCollection());
+ assertThat("was " + actualCollection, actualCollection, containsInAnyOrder(
+ allOf(hasProperty("uuid", is("1")), hasProperty("isInstantiationTemplateExists", is(false))),
+ allOf(hasProperty("uuid", is("3")), hasProperty("isInstantiationTemplateExists", is(false)))
+ ));
+ }
+
+ private Collection<Service> createGivenCollection(){
+ Service service1 = new Service();
+ Service service2 = new Service();
+ service1.setUuid("1");
+ service2.setUuid("3");
+ return ImmutableList.of(service1, service2);
+ }
+
}
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/MsoRequestBuilderTest.java b/vid-app-common/src/test/java/org/onap/vid/services/MsoRequestBuilderTest.java
index efd9e2b27..71d38b3f8 100644
--- a/vid-app-common/src/test/java/org/onap/vid/services/MsoRequestBuilderTest.java
+++ b/vid-app-common/src/test/java/org/onap/vid/services/MsoRequestBuilderTest.java
@@ -21,6 +21,10 @@
package org.onap.vid.services;
import static com.google.common.collect.Maps.newHashMap;
+import static java.util.Collections.EMPTY_LIST;
+import static java.util.Collections.EMPTY_MAP;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonNodeAbsent;
import static net.javacrumbs.jsonunit.JsonMatchers.jsonPartEquals;
@@ -41,7 +45,6 @@ import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -78,7 +81,7 @@ import org.onap.vid.mso.model.ModelInfo;
import org.onap.vid.mso.model.NetworkInstantiationRequestDetails;
import org.onap.vid.mso.model.ServiceDeletionRequestDetails;
import org.onap.vid.mso.model.ServiceInstantiationRequestDetails;
-import org.onap.vid.mso.model.UserParamMap;
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue;
import org.onap.vid.mso.model.VfModuleMacro;
import org.onap.vid.mso.model.VfModuleOrVolumeGroupRequestDetails;
import org.onap.vid.mso.model.VnfInstantiationRequestDetails;
@@ -163,7 +166,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
private void createMacroServiceInfo_WithUserProvidedNamingFalse_ServiceInfoIsAsExpected(boolean withVfmodules, boolean disabledHoming) throws IOException {
ServiceInstantiation serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(true,
- createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, Collections.EMPTY_LIST, false),
+ createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, EMPTY_LIST, false),
1,
false, PROJECT_NAME, true);
URL resource;
@@ -181,7 +184,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
msoRequestBuilder.generateMacroServiceInstantiationRequest(null, serviceInstantiationPayload, serviceInstantiationPayload.getInstanceName(), "az2016");
String expected = IOUtils.toString(resource, "UTF-8");
- MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
+ assertThat(result, jsonEquals(expected));
}
@Test
@@ -233,7 +236,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
}
private ServiceInstantiation generateALaCarteServiceDeletionPayload() {
- return generateMockAlaCarteServiceDeletionPayload(false, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
+ return generateMockAlaCarteServiceDeletionPayload(false, EMPTY_MAP, EMPTY_MAP, EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
}
@Test
@@ -255,7 +258,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
}
private ServiceInstantiation generateServiceDeletionPayload() {
- return generateMockServiceDeletionPayload(false, Collections.EMPTY_MAP, Collections.EMPTY_MAP, Collections.EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
+ return generateMockServiceDeletionPayload(false, EMPTY_MAP, EMPTY_MAP, EMPTY_MAP, 1, true, PROJECT_NAME, false, "VNF_API", "1234567890");
}
@DataProvider
@@ -301,7 +304,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
public static Object[][] testBuildVnfInstanceParamsDataProvider(Method test) {
return new Object[][]{
{
- Collections.EMPTY_LIST,
+ EMPTY_LIST,
ImmutableList.of(
ImmutableList.of(ImmutableMap.of("k1", "v1", "k2", "v2")),
ImmutableList.of(ImmutableMap.of("k3", "v3", "k2", "v2"))
@@ -313,23 +316,23 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
ImmutableList.of(
ImmutableList.of(ImmutableMap.of("k1", "v1", "k2", "v2")),
ImmutableList.of(ImmutableMap.of("k3", "v3", "k2", "v2")),
- ImmutableList.of(Collections.EMPTY_MAP),
- Collections.singletonList(null)
+ ImmutableList.of(EMPTY_MAP),
+ singletonList(null)
),
ImmutableList.of(ImmutableMap.of("k1", "v1", "k2", "v2", "k3", "v3", "j1", "w1"))
},
{
- Collections.EMPTY_LIST,
+ EMPTY_LIST,
Arrays.asList(null, null),
- Collections.EMPTY_LIST //mso is expect to empty list and not list with empty map
+ EMPTY_LIST //mso is expect to empty list and not list with empty map
},
{
- ImmutableList.of(Collections.EMPTY_MAP),
+ ImmutableList.of(EMPTY_MAP),
ImmutableList.of(
- ImmutableList.of(Collections.EMPTY_MAP),
- ImmutableList.of(Collections.EMPTY_MAP)
+ ImmutableList.of(EMPTY_MAP),
+ ImmutableList.of(EMPTY_MAP)
),
- Collections.EMPTY_LIST //mso is expect to empty list and not list with empty map
+ EMPTY_LIST //mso is expect to empty list and not list with empty map
}
};
}
@@ -347,24 +350,27 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
@DataProvider
public static Object[][] vfModuleRequestDetails(Method test) {
return new Object[][]{
- {"cc3514e3-5a33-55df-13ab-12abad84e7cc", true, "/payload_jsons/vfmodule_instantiation_request.json"},
- {null, true, "/payload_jsons/vfmodule_instantiation_request_without_volume_group.json"},
- {null, false, "/payload_jsons/vfmodule_instantiation_request_without_instance_name.json"}
+ {"cc3514e3-5a33-55df-13ab-12abad84e7cc", true, false, "/payload_jsons/vfmodule_instantiation_request.json"},
+ {null, true, null, "/payload_jsons/vfmodule_instantiation_request_without_volume_group.json"},
+ {null, false, true, "/payload_jsons/vfmodule_instantiation_request_without_instance_name.json"}
};
}
@Test(dataProvider = "vfModuleRequestDetails")
- public void createVfModuleRequestDetails_detailsAreAsExpected(String volumeGroupInstanceId, boolean isUserProvidedNaming, String fileName) throws IOException {
+ public void createVfModuleRequestDetails_detailsAreAsExpected(String volumeGroupInstanceId, boolean isUserProvidedNaming, Boolean usePreload, String fileName) throws IOException {
ModelInfo siModelInfo = createServiceModelInfo();
ModelInfo vnfModelInfo = createVnfModelInfo(true);
List<Map<String, String>> instanceParams = ImmutableList.of(ImmutableMap.of("vmx_int_net_len", "24",
"vre_a_volume_size_0", "120"));
- Map<String, String> supplementaryParams = ImmutableMap.of("vre_a_volume_size_0", "100",
- "availability_zone_0", "mtpocdv-kvm-az01");
+ List<UserParamNameAndValue> supplementaryParams = ImmutableList.of(
+ new UserParamNameAndValue("vre_a_volume_size_0", "100"),
+ new UserParamNameAndValue("availability_zone_0", "mtpocdv-kvm-az01")
+ );
+
VfModule vfModule = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1", "56e2b103-637c-4d1a-adc8-3a7f4a6c3240",
"72d9d1cd-f46d-447a-abdb-451d6fb05fa8", instanceParams, supplementaryParams,
- (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion" : null), "myVgName", true);
+ (isUserProvidedNaming ? "vmxnjr001_AVPN_base_vRE_BV_expansion" : null), "myVgName", true, usePreload);
String serviceInstanceId = "aa3514e3-5a33-55df-13ab-12abad84e7aa";
String vnfInstanceId = "bb3514e3-5a33-55df-13ab-12abad84e7bb";
@@ -378,26 +384,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
final RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> result = msoRequestBuilder.generateVfModuleInstantiationRequest(
vfModule, siModelInfo, serviceInstanceId,
vnfModelInfo, vnfInstanceId, volumeGroupInstanceId, "pa0916", "VNF_API");
- MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
- }
-
- @DataProvider
- public static Object[][] expectedAggregatedParams() {
- return new Object[][]{
- {ImmutableMap.of("a", "b", "c", "d"), ImmutableMap.of("e", "f", "g", "h"), ImmutableList.of(ImmutableMap.of("c", "d", "a", "b", "e", "f", "g", "h"))},
- {ImmutableMap.of("a", "b", "c", "g"), ImmutableMap.of("c", "d", "e", "f"), ImmutableList.of(ImmutableMap.of("a", "b", "c", "d", "e", "f"))},
- {ImmutableMap.of(), ImmutableMap.of("c", "d", "e", "f"), ImmutableList.of(ImmutableMap.of("c", "d", "e", "f"))},
- {ImmutableMap.of("a", "b", "c", "g"), ImmutableMap.of(), ImmutableList.of(ImmutableMap.of("a", "b", "c", "g"))},
- {ImmutableMap.of(), ImmutableMap.of(), ImmutableList.of()},
- {null, ImmutableMap.of(), ImmutableList.of()},
- {ImmutableMap.of(), null, ImmutableList.of()},
- };
- }
-
- @Test(dataProvider = "expectedAggregatedParams")
- public void testAggregateInstanceParamsAndSuppFile(Map<String, String> instanceParams, Map<String, String> suppParams, List<UserParamMap<String, String>> expected) {
- List<UserParamMap<String, String>> aggParams = msoRequestBuilder.aggregateAllInstanceParams(instanceParams, suppParams);
- assertThat("Aggregated params are not as expected", aggParams, equalTo(expected));
+ assertThat(result, jsonEquals(expected).when(IGNORING_ARRAY_ORDER));
}
@Test
@@ -406,10 +393,11 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
VfModule vfModule = createVfModule("201673MowAvpnVpeBvL..AVPN_vRE_BV..module-1",
"56e2b103-637c-4d1a-adc8-3a7f4a6c3240",
"72d9d1cd-f46d-447a-abdb-451d6fb05fa8",
- Collections.emptyList(),
- Collections.emptyMap(),
+ emptyList(),
+ emptyList(),
"vmxnjr001_AVPN_base_vRE_BV_expansion",
"myVgName",
+ true,
true);
vfModule.getModelInfo().setModelInvariantId("ff5256d2-5a33-55df-13ab-12abad84e7ff");
vfModule.getModelInfo().setModelVersion("1");
@@ -437,7 +425,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
@Test(dataProvider = "expectedNetworkRequestDetailsParameters")
public void createNetworkRequestDetails_detailsAreAsExpected(String networkName, String filePath) throws IOException {
- List<NetworkDetails> networkDetails = Collections.singletonList(new NetworkDetails(networkName, "ab153b6e-c364-44c0-bef6-1f2982117f04"));
+ List<NetworkDetails> networkDetails = singletonList(new NetworkDetails(networkName, "ab153b6e-c364-44c0-bef6-1f2982117f04"));
final List<Network> networksList = new ArrayList<>(createNetworkList(null, networkDetails, true).values());
ModelInfo siModelInfo = createServiceModelInfo();
String serviceInstanceId = "aa3514e3-5a33-55df-13ab-12abad84e7aa";
@@ -495,7 +483,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
@Test
public void checkIfNullProjectNameSentToMso() {
ServiceInstantiation serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(true,
- createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, Collections.EMPTY_LIST, false),
+ createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, EMPTY_LIST, false),
1,
false, null, false);
RequestDetailsWrapper<ServiceInstantiationRequestDetails> result =
@@ -503,7 +491,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
JsonNode jsonNode = new ObjectMapper().valueToTree(result.requestDetails);
Assert.assertTrue(jsonNode.get("project").isNull());
serviceInstantiationPayload = generateMockMacroServiceInstantiationPayload(true,
- createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, Collections.EMPTY_LIST, false),
+ createVnfList(vfModuleInstanceParamsMapWithParamsToRemove, EMPTY_LIST, false),
1,
false, "not null", false);
result = msoRequestBuilder.generateMacroServiceInstantiationRequest(null, serviceInstantiationPayload, serviceInstantiationPayload.getInstanceName(), "az2016");
@@ -538,7 +526,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
"}";
Vnf vnfDetails = new Vnf(createVnfModelInfo(true), "productFamily", "instanceName", Action.Delete.name(), "platform", "AAIAIC25", null,
"092eb9e8e4b7412e8787dd091bc58e86", null, null, false, "VNF_INSTANCE_ID", null, UUID.randomUUID().toString(), null, null,
- null);
+ null, "originalName");
RequestDetailsWrapper<VnfInstantiationRequestDetails> result =
msoRequestBuilder.generateDeleteVnfRequest(vnfDetails, "az2018");
MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
@@ -569,7 +557,8 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
" }" +
" }" +
"}";
- VfModule vfModuleDetails = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME, null, new HashMap<>(), "vmxnjr001_AVPN_base_vPE_BV_base", null, true);
+ VfModule vfModuleDetails = createVfModule("201673MowAvpnVpeBvL..AVPN_base_vPE_BV..module-0", VF_MODULE_0_MODEL_VERSION_ID, VF_MODULE_0_MODEL_CUSTOMIZATION_NAME,
+ null, emptyList(), "vmxnjr001_AVPN_base_vPE_BV_base", null, true, true);
RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> result =
msoRequestBuilder.generateDeleteVfModuleRequest(vfModuleDetails, "az2018");
MsoOperationalEnvironmentTest.assertThatExpectationIsLikeObject(expected, result);
@@ -636,16 +625,25 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
@Test
public void generateReplaceVfModuleRequest_whenThereAreSupplementaryParams_thenTheyAreAddToUserParams() {
- String expectedParams = "[{"
- + " \"vre_a_volume_size_0\" : \"100\","
- + " \"vmx_int_net_len\" : \"24\","
- + " \"availability_zone_0\": \"abc\""
- + " }]";
-
- Map<String, String> supplementaryParams = ImmutableMap.of(
- "vre_a_volume_size_0", "100",
- "vmx_int_net_len", "24",
- "availability_zone_0", "abc"
+ String expectedParams = "["
+ + " {"
+ + " \"name\": \"vre_a_volume_size_0\","
+ + " \"value\": \"100\""
+ + " },"
+ + " {"
+ + " \"name\": \"vmx_int_net_len\","
+ + " \"value\": \"24\""
+ + " },"
+ + " {"
+ + " \"name\": \"availability_zone_0\","
+ + " \"value\": \"abc\""
+ + " }"
+ + " ]";
+
+ List<UserParamNameAndValue> supplementaryParams = ImmutableList.of(
+ new UserParamNameAndValue( "vre_a_volume_size_0", "100"),
+ new UserParamNameAndValue("vmx_int_net_len", "24"),
+ new UserParamNameAndValue("availability_zone_0", "abc")
);
assertThat(generatedVfModuleReplaceRequest(null, null, supplementaryParams),
@@ -662,7 +660,7 @@ public class MsoRequestBuilderTest extends AsyncInstantiationBaseTest {
}
private RequestDetailsWrapper<VfModuleOrVolumeGroupRequestDetails> generatedVfModuleReplaceRequest(
- Boolean retainAssignments, Boolean retainVolumeGroups, Map<String, String> supplementaryParams) {
+ Boolean retainAssignments, Boolean retainVolumeGroups, List<UserParamNameAndValue> supplementaryParams) {
when(featureManager.isActive(Features.FLAG_1810_CR_ADD_CLOUD_OWNER_TO_MSO_REQUEST)).thenReturn(true);
when(aaiClient.getCloudOwnerByCloudRegionId("regionOne")).thenReturn("irma-aic");
diff --git a/vid-app-common/src/test/java/org/onap/vid/services/UserParamsContainerTest.kt b/vid-app-common/src/test/java/org/onap/vid/services/UserParamsContainerTest.kt
new file mode 100644
index 000000000..511c4e5cb
--- /dev/null
+++ b/vid-app-common/src/test/java/org/onap/vid/services/UserParamsContainerTest.kt
@@ -0,0 +1,57 @@
+package org.onap.vid.services
+
+import org.hamcrest.CoreMatchers.equalTo
+import org.hamcrest.MatcherAssert
+import org.onap.vid.mso.model.ServiceInstantiationRequestDetails.UserParamNameAndValue
+import org.testng.annotations.DataProvider
+import org.testng.annotations.Test
+
+class UserParamsContainerTest {
+
+ @DataProvider
+ fun userParamsDataProvider(): Array<Array<Any?>>? {
+ return arrayOf(
+ arrayOf<Any?>(
+ mapOf("a" to "b", "c" to "d"),
+ listOf(UserParamNameAndValue("e", "f"), UserParamNameAndValue("g", "h")),
+ mapOf("c" to "d", "a" to "b", "e" to "f", "g" to "h")
+ ),
+ arrayOf<Any?>(
+ mapOf("a" to "b", "c" to "g"),
+ listOf(UserParamNameAndValue("c", "d") , UserParamNameAndValue("e", "f")),
+ mapOf("c" to "d", "a" to "b", "e" to "f")
+ ),
+ arrayOf<Any?>(
+ emptyMap<String,String>(),
+ listOf(UserParamNameAndValue("c", "d"), UserParamNameAndValue("e", "f")),
+ mapOf("c" to "d", "e" to "f")
+ ),
+ arrayOf<Any?>(
+ mapOf("a" to "b", "c" to "d"),
+ emptyList<UserParamNameAndValue>(),
+ mapOf("a" to "b", "c" to "d")
+ ),
+ arrayOf<Any?>(
+ emptyMap<String,String>(),
+ emptyList<UserParamNameAndValue>(),
+ emptyMap<String,String>()
+ ),
+ arrayOf(
+ null,
+ emptyList<UserParamNameAndValue>(),
+ emptyMap<String,String>()
+ ),
+ arrayOf<Any?>(
+ emptyMap<String,String>(),
+ null,
+ emptyMap<String,String>()
+ )
+ )
+ }
+
+ @Test(dataProvider = "userParamsDataProvider")
+ fun testUserParamsConvertorCtor(instanceParams: Map<String, String>?, suppParams: List<UserParamNameAndValue>?, expected: Map<String, String>) {
+ val aggParams: Map<String, String> = UserParamsContainer(instanceParams, suppParams).params
+ MatcherAssert.assertThat("Aggregated params are not as expected", aggParams, equalTo(expected))
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java b/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java
index 862b8db8f..71f7ee015 100644
--- a/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java
+++ b/vid-app-common/src/test/java/org/onap/vid/testUtils/TestUtils.java
@@ -21,9 +21,7 @@
package org.onap.vid.testUtils;
import static com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper;
-import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toList;
-import static java.util.stream.Collectors.toMap;
import static org.apache.commons.beanutils.PropertyUtils.getPropertyDescriptors;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.text.CharacterPredicates.DIGITS;
@@ -52,7 +50,9 @@ import java.lang.reflect.Field;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;
import javax.ws.rs.client.Client;
@@ -61,7 +61,6 @@ import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
@@ -174,15 +173,27 @@ public class TestUtils {
}
public static String[] allPropertiesOf(Class<?> aClass) {
- return Arrays.stream(getPropertyDescriptors(aClass))
+ return getPropertyDescriptorsRecursively(aClass).stream()
.map(PropertyDescriptor::getDisplayName)
+ .distinct()
.toArray(String[]::new);
}
+ private static List<PropertyDescriptor> getPropertyDescriptorsRecursively(Class<?> aClass) {
+ List<PropertyDescriptor> result = new LinkedList<>();
+
+ for (Class<?> i = aClass; i != null && i != Object.class; i = i.getSuperclass()) {
+ Collections.addAll(result, getPropertyDescriptors(i));
+ }
+
+ return result;
+ }
+
private static <T> List<String> allStringPropertiesOf(T object) {
- return Arrays.stream(getPropertyDescriptors(object.getClass()))
+ return getPropertyDescriptorsRecursively(object.getClass()).stream()
.filter(descriptor -> descriptor.getPropertyType().isAssignableFrom(String.class))
.map(PropertyDescriptor::getDisplayName)
+ .distinct()
.collect(toList());
}
@@ -221,16 +232,15 @@ public class TestUtils {
* @return The modified object
*/
public static <T> T setStringsInStringProperties(T object) {
- try {
- final List<String> stringFields = allStringPropertiesOf(object);
-
- BeanUtils.populate(object, stringFields.stream()
- .collect(toMap(identity(), identity())));
+ allStringPropertiesOf(object).forEach(it -> {
+ try {
+ FieldUtils.writeField(object, it, it, true);
+ } catch (IllegalAccessException e) {
+ // YOLO
+ }
+ });
- return object;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
+ return object;
}
public static void registerCloudConfigurationValueGenerator() {
diff --git a/vid-app-common/src/test/resources/example.features.properties b/vid-app-common/src/test/resources/example.features.properties
new file mode 100644
index 000000000..e8ac3eb65
--- /dev/null
+++ b/vid-app-common/src/test/resources/example.features.properties
@@ -0,0 +1 @@
+FLAG_1810_AAI_LOCAL_CACHE=true \ No newline at end of file
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfModuleDelete1Create1None1Request.json b/vid-app-common/src/test/resources/payload_jsons/vfModuleDelete1Create1None1Request.json
index 642c2aac9..a4f609a28 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfModuleDelete1Create1None1Request.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfModuleDelete1Create1None1Request.json
@@ -10,6 +10,7 @@
"instanceId": "VF_MODULE_INSTANCE_ID",
"action": "Create",
"lcpCloudRegionId": "AAIAIC25",
+ "legacyRegion": "some legacy region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
"modelInfo": {
"modelInvariantId": "b34833bb-6aa9-4ad6-a831-70b06367a091",
@@ -36,6 +37,7 @@
"provStatus": "Prov Status",
"inMaint": false,
"lcpCloudRegionId": "AAIAIC25",
+ "legacyRegion": "some legacy region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
"modelInfo": {
"modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
@@ -59,6 +61,7 @@
"provStatus": "Prov Status",
"inMaint": false,
"lcpCloudRegionId": "AAIAIC25",
+ "legacyRegion": "some legacy region",
"tenantId": "092eb9e8e4b7412e8787dd091bc58e86",
"modelInfo": {
"modelInvariantId": "7253ff5c-97f0-4b8b-937c-77aeb4d79aa1",
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfmodule/replace_vfmodule__payload_to_mso.json b/vid-app-common/src/test/resources/payload_jsons/vfmodule/replace_vfmodule__payload_to_mso.json
index 103985c96..26aa7d70c 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfmodule/replace_vfmodule__payload_to_mso.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfmodule/replace_vfmodule__payload_to_mso.json
@@ -33,6 +33,7 @@
}],
"requestParameters": {
"userParams": [],
+ "usePreload": false,
"testApi": "GR_API"
},
"modelInfo": {
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json b/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json
index d215a4331..16d369ba7 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__fe_input_cypress.json
@@ -111,7 +111,7 @@
"rollbackOnFailure": false,
"isALaCarte": true,
"collectionResources": {},
- "testApi": "VNF_API",
+ "testApi": "GR_API",
"vidNotions": {
"instantiationUI": "legacy",
"modelCategory": "other",
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__payload_to_mso.json b/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__payload_to_mso.json
index 91f80e9f1..5c258f66b 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__payload_to_mso.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfmodule/upgrade_vfmodule_e2e__payload_to_mso.json
@@ -36,7 +36,7 @@
"retainAssignments": false,
"usePreload" : true,
"userParams": [],
- "testApi": "VNF_API"
+ "testApi": "GR_API"
},
"modelInfo": {
"modelType": "vfModule",
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request.json b/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request.json
index 1bce76097..e5e3e9fab 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request.json
@@ -58,12 +58,21 @@
}
],
"requestParameters": {
- "usePreload": true,
- "userParams": [{
- "vre_a_volume_size_0" : "100",
- "vmx_int_net_len" : "24",
- "availability_zone_0": "mtpocdv-kvm-az01"
- }],
+ "usePreload": false,
+ "userParams": [
+ {
+ "name": "vre_a_volume_size_0",
+ "value": "100"
+ },
+ {
+ "name": "vmx_int_net_len",
+ "value": "24"
+ },
+ {
+ "name": "availability_zone_0",
+ "value": "mtpocdv-kvm-az01"
+ }
+ ],
"testApi" : "VNF_API"
}
}
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_instance_name.json b/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_instance_name.json
index 1c0d2b981..026c16f7b 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_instance_name.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_instance_name.json
@@ -49,11 +49,20 @@
],
"requestParameters": {
"usePreload": true,
- "userParams": [{
- "vre_a_volume_size_0" : "100",
- "vmx_int_net_len" : "24",
- "availability_zone_0": "mtpocdv-kvm-az01"
- }],
+ "userParams": [
+ {
+ "name": "vre_a_volume_size_0",
+ "value": "100"
+ },
+ {
+ "name": "vmx_int_net_len",
+ "value": "24"
+ },
+ {
+ "name": "availability_zone_0",
+ "value": "mtpocdv-kvm-az01"
+ }
+ ],
"testApi" : "VNF_API"
}
}
diff --git a/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_volume_group.json b/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_volume_group.json
index 3581a475a..87db583e7 100644
--- a/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_volume_group.json
+++ b/vid-app-common/src/test/resources/payload_jsons/vfmodule_instantiation_request_without_volume_group.json
@@ -49,12 +49,21 @@
}
],
"requestParameters": {
- "usePreload": true,
- "userParams": [{
- "vre_a_volume_size_0" : "100",
- "vmx_int_net_len" : "24",
- "availability_zone_0": "mtpocdv-kvm-az01"
- }],
+ "usePreload": false,
+ "userParams": [
+ {
+ "name": "vre_a_volume_size_0",
+ "value": "100"
+ },
+ {
+ "name": "vmx_int_net_len",
+ "value": "24"
+ },
+ {
+ "name": "availability_zone_0",
+ "value": "mtpocdv-kvm-az01"
+ }
+ ],
"testApi" : "VNF_API"
}
}
diff --git a/vid-app-common/src/test/resources/responses/aai/listServicesByOwningEntity.json b/vid-app-common/src/test/resources/responses/aai/listServicesByOwningEntity.json
new file mode 100644
index 000000000..a97a74a06
--- /dev/null
+++ b/vid-app-common/src/test/resources/responses/aai/listServicesByOwningEntity.json
@@ -0,0 +1,97 @@
+{
+ "owning-entity": [
+ {
+ "owning-entity-id": "43b8a85a-0421-4265-9069-117dd6526b8a",
+ "owning-entity-name": "Melissa",
+ "resource-version": "1527418700853",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/256cddb4-3aa1-43cc-a08f-315bb50b275e/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/af9d52f9-13b2-4657-a198-463677f82dc0",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "256cddb4-3aa1-43cc-a08f-315bb50b275e"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "MSO-dev-service-type"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "af9d52f9-13b2-4657-a198-463677f82dc0"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "xbghrftgr_shani"
+ }
+ ]
+ },
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/e02fd6f2-7fc2-434b-a92d-15abdb24b68d/service-subscriptions/service-subscription/JUST-another-service-type/service-instances/service-instance/49769492-5def-4c89-8e73-b236f958fa40",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "e02fd6f2-7fc2-434b-a92d-15abdb24b68d"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "JUST-another-service-type"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "49769492-5def-4c89-8e73-b236f958fa40"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "fghghfhgf"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "owning-entity-id": "26dcc4aa-725a-447d-8346-aa26dfaa4eb7",
+ "owning-entity-name": "Kobe",
+ "resource-version": "1527418700844",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/256cddb4-3aa1-43cc-a08f-315bb50b275e/service-subscriptions/service-subscription/MSO-dev-service-type/service-instances/service-instance/1d8fd482-2f53-4d62-a7bd-20e4bab14c45",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "256cddb4-3aa1-43cc-a08f-315bb50b275e"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "MSO-dev-service-type"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "1d8fd482-2f53-4d62-a7bd-20e4bab14c45"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "Bryant"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/vid-app-common/src/test/resources/responses/aai/listServicesByProject.json b/vid-app-common/src/test/resources/responses/aai/listServicesByProject.json
new file mode 100644
index 000000000..6d6b09f78
--- /dev/null
+++ b/vid-app-common/src/test/resources/responses/aai/listServicesByProject.json
@@ -0,0 +1,95 @@
+{
+ "project": [
+ {
+ "project-name": "x1",
+ "resource-version": "1527026201826",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.Uses",
+ "related-link": "/aai/v12/business/customers/customer/a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb/service-subscriptions/service-subscription/Emanuel/service-instances/service-instance/3f826016-3ac9-4928-9561-beee75fd91d5",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "Emanuel"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "3f826016-3ac9-4928-9561-beee75fd91d5"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "Lital_SRIOV2_001"
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "project-name": "y2",
+ "resource-version": "1527026341826",
+ "relationship-list": {
+ "relationship": [
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.BelongsTo",
+ "related-link": "/aai/v12/business/customers/customer/3d15d7ea-4174-49b6-89ec-e569381f7231/service-subscriptions/service-subscription/vMOG/service-instances/service-instance/7e4f8130-5dee-47c4-8770-1abc5f5ded83",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "3d15d7ea-4174-49b6-89ec-e569381f7231"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "vMOG"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "7e4f8130-5dee-47c4-8770-1abc5f5ded83"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "justAname"
+ }
+ ]
+ },
+ {
+ "related-to": "service-instance",
+ "relationship-label": "org.onap.relationships.inventory.Uses",
+ "related-link": "/aai/v12/business/customers/customer/a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb/service-subscriptions/service-subscription/Yoda/service-instances/service-instance/ff2d9326-1ef5-4760-aba0-0eaf372ae675",
+ "relationship-data": [
+ {
+ "relationship-key": "customer.global-customer-id",
+ "relationship-value": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb"
+ },
+ {
+ "relationship-key": "service-subscription.service-type",
+ "relationship-value": "Yoda"
+ },
+ {
+ "relationship-key": "service-instance.service-instance-id",
+ "relationship-value": "ff2d9326-1ef5-4760-aba0-0eaf372ae675"
+ }
+ ],
+ "related-to-property": [
+ {
+ "property-key": "service-instance.service-instance-name",
+ "property-value": "anotherName"
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+}