aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOfir Sonsino <os0695@att.com>2017-09-20 14:08:19 +0300
committerOfir Sonsino <os0695@att.com>2017-09-20 14:14:56 +0300
commit1ba64a4a45f26e8bdb58e866e540aa58f32e2e52 (patch)
treedac3ada662bb141fe986526d13b2436032e5012e
parentcbdd17f586a4914890bd2b26ee91be135568f38c (diff)
Change management and PNF support
Issue-ID: VID-44, VID-48, VID-49, VID-50, VID-51, VID-52 Change-Id: I83e940aad2e4e294a0927b546c4c08ca8e539a65 Signed-off-by: Ofir Sonsino <os0695@att.com>
-rwxr-xr-xepsdk-app-onap/.classpath6
-rwxr-xr-xepsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties7
-rwxr-xr-xepsdk-app-onap/src/main/webapp/WEB-INF/jsp/serviceModels.jsp18
-rwxr-xr-xepsdk-app-onap/src/main/webapp/WEB-INF/jsp/welcome.jsp2
-rwxr-xr-xepsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/app.js5
-rwxr-xr-xepsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/appDS2.js3
-rw-r--r--epsdk-app-onap/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js1
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/aai/util/AAIRestInterface.java48
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/RelatedTo.java36
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClient.java514
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClientInterface.java11
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/AaiGetVnfResponse.java28
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/ServiceProperties.java90
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/VnfResult.java44
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelatedToProperty.java34
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/model/Relationship.java55
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipData.java29
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipList.java24
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/aai/model/ServiceRelationships.java90
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/asdc/beans/tosca/ToscaMetadata.java30
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/asdc/parser/ToscaParserImpl2.java2
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementRequest.java63
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementResponse.java19
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CloudConfiguration.java55
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CmResponse.java17
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/LeanCloudConfiguration.java20
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfo.java138
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfoOfRelatedInstance.java122
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/MsoRequestDetails.java31
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstance.java29
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstanceList.java23
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetails.java56
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetailsWrapper.java9
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestInfo.java69
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestParameters.java44
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/changeManagement/UpdateRequestInfo.java26
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/controller/AaiController.java1728
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/controller/ChangeManagementController.java71
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/controller/MsoConfig.java29
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/controller/MsoController.java528
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/controller/PolicyController.java90
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/controller/SchedulerController.java244
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/controller/VidController.java1
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/factories/MsoRequestFactory.java15
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/model/CommandProperty.java12
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/model/VersionByInvariantIdsRequest.java11
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/model/VolumeGroup.java2
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/model/Workflow.java47
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/MsoBusinessLogic.java415
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/MsoClientFactory.java37
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/MsoInterface.java75
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClient.java85
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClientNew.java216
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/MsoProperties.java21
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterface.java73
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceFactory.java32
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceIfc.java15
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/RestMsoImplementation.java326
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoBusinessLogicNew.java67
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoRestClientNew.java333
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/rest/RelatedModel.java4
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestDetails.java25
-rwxr-xr-xvid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestList.java6
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestWrapper.java35
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Response.java54
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RestInterface.java81
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Task.java119
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/mso/rest/TaskList.java16
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyProperties.java26
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyResponseWrapper.java56
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInt.java67
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterface.java234
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceFactory.java14
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceIfc.java58
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyUtil.java71
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/RestObject.java68
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/policy/rest/RequestDetails.java107
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/properties/MsoClientConfiguration.java9
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/roles/Role.java2
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObject.java44
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/GetTimeSlotsRestObject.java11
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostCreateNewVnfRestObject.java10
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostSubmitVnfChangeRestObject.java10
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/RestObject.java39
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerProperties.java24
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrapper.java71
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/GetTimeSlotsWrapper.java5
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostCreateNewVnfWrapper.java39
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostSubmitVnfChangeTimeSlotsWrapper.java38
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/SchedulerResponseWrapper.java57
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInt.java42
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterface.java208
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceFactory.java15
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceIfc.java21
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerUtil.java100
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/scheduler/rest/RequestDetails.java106
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/services/AaiService.java9
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/services/AaiServiceImpl.java35
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementService.java14
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementServiceImpl.java109
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowService.java9
-rw-r--r--vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowServiceImpl.java40
-rwxr-xr-xvid-app-common/src/main/resources/json/mso/modelInfo13
-rwxr-xr-xvid-app-common/src/main/resources/json/mso/request10
-rwxr-xr-xvid-app-common/src/main/resources/json/mso/requestInfo8
-rwxr-xr-xvid-app-common/src/main/resources/json/mso/requestStatus10
-rw-r--r--vid-app-common/src/main/resources/mso_complete_manual_task.json5
-rw-r--r--vid-app-common/src/main/resources/mso_create_instance_response.json6
-rw-r--r--vid-app-common/src/main/resources/mso_get_manual_task_by_request_id.json23
-rw-r--r--vid-app-common/src/main/resources/mso_get_orchestration_requests.json88
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/css/bootstrap.min.css6
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.eotbin0 -> 20127 bytes
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.svg288
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.ttfbin0 -> 45404 bytes
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woffbin0 -> 23424 bytes
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff2bin0 -> 18028 bytes
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/bootstrap/js/bootstrap.min.js7
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js136
-rw-r--r--vid-app-common/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js1
-rw-r--r--vid-app-common/src/main/webapp/app/vid/images/Calendar.svg39
-rw-r--r--vid-app-common/src/main/webapp/app/vid/images/Calendar_blue.svg45
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/constants/componentConstants.js26
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/constants/fieldConstants.js153
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/constants/vidConfiguration.js10
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/InstantiationController.js3
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/ServiceModelController.js4
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/VidApp.js5
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js15
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/controller/change-management.controller.js138
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/directives/angularjs-datetime-picker.js361
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/filters/change-managements-by-statuses.filter.js22
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/filters/date.filter.js18
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.css3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.html12
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.controller.js33
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.css3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.html12
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.controller.js56
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html7
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.css3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.html12
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.css3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.html12
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js369
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css130
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html68
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js455
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css145
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html101
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.css7
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.html12
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js296
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/services/change-management.service.js76
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/services/creationService.js4
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/services/msoService.js376
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/services/schedulerService.js104
-rw-r--r--vid-app-common/src/main/webapp/app/vid/scripts/view-models/change-management.html112
-rwxr-xr-xvid-app-common/src/main/webapp/app/vid/scripts/view-models/instantiate.htm3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/angularjs-datetime-picker.css76
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/change-management-icons.css82
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/change-management.css157
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/common.css3
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.eotbin0 -> 5200 bytes
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.svg23
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.ttfbin0 -> 5036 bytes
-rw-r--r--vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.woffbin0 -> 5112 bytes
-rw-r--r--vid-app-common/src/test/java/org/opencomp/vid/controller/MsoControllerTest.java112
-rw-r--r--vid-app-common/src/test/java/org/opencomp/vid/controller/VidControllerTest.java16
-rw-r--r--vid-app-common/src/test/java/org/openecomp/vid/services/ChangeManagementServiceTest.java29
-rw-r--r--vid-app-common/src/test/resources/WEB-INF/conf/system.properties24
-rw-r--r--vid-app-common/src/test/resources/WEB-INF/jsp/serviceModels.jsp10
-rw-r--r--vid-app-common/src/test/resources/WEB-INF/jsp/welcome.jsp5
-rw-r--r--vid-app-common/src/test/resources/mso.properties16
-rw-r--r--vid-app-common/src/test/resources/msoRequest.json25
174 files changed, 11020 insertions, 1791 deletions
diff --git a/epsdk-app-onap/.classpath b/epsdk-app-onap/.classpath
index ede37b2b3..f210876be 100755
--- a/epsdk-app-onap/.classpath
+++ b/epsdk-app-onap/.classpath
@@ -11,12 +11,6 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
- <classpathentry kind="src" output="target/test-classes" path="src/test/java">
- <attributes>
- <attribute name="optional" value="true"/>
- <attribute name="maven.pomderived" value="true"/>
- </attributes>
- </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
diff --git a/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties b/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties
index e7623665d..0cbc3126a 100755
--- a/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties
+++ b/epsdk-app-onap/src/main/webapp/WEB-INF/conf/system.properties
@@ -165,10 +165,15 @@ mso.restapi.vf.module.instance=/serviceInstances/v4/<service_instance_id>/vnfs/<
mso.restapi.volume.group.instance=/serviceInstances/v4/<service_instance_id>/vnfs/<vnf_instance_id>/volumeGroups
mso.restapi.get.orc.req=/orchestrationRequests/v4
mso.restapi.get.orc.reqs=/orchestrationRequests/v4?
+mso.restapi.get.man.tasks=/tasks/v1
vid.truststore.filename=/opt/app/vid/etc/vid_keystore.jks
mso.dme2.client.timeout=30000
mso.dme2.client.read.timeout=120000
vid.truststore.filename=vid_keystore.jks
vid.truststore.passwd.x=OBF:1wgg1wfq1uus1uui1x131x0r1x1v1x1j1uvo1uve1wg81wfi
+scheduler.create.new.vnf.change.instance=/v1/ChangeManagement/schedules/
+scheduler.get.time.slots=/v1/ChangeManagement/schedules/
+scheduler.server.url=http://BYO.scheduler:8989/scheduler
-
+scheduler.submit.new.vnf.change=/v1/ChangeManagement/schedules/{scheduleId}/approvals
+scheduler.get.schedules=/v1/ChangeManagement/schedules/scheduleDetails/ \ No newline at end of file
diff --git a/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/serviceModels.jsp b/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/serviceModels.jsp
index 6d2305108..d0c36d47a 100755
--- a/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/serviceModels.jsp
+++ b/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/serviceModels.jsp
@@ -6,6 +6,9 @@
<link rel="stylesheet" type="text/css" href="app/vid/styles/instantiate.css" />
<link rel="stylesheet" type="text/css" href="app/vid/styles/vidTree.css" />
<link rel="stylesheet" type="text/css" href="app/vid/styles/dialogs.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/styles/angularjs-datetime-picker.css"></link>
+<link rel="stylesheet" type="text/css" href="app/vid/external/bootstrap/css/bootstrap.min.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/styles/common.css" />
<script>
@@ -17,14 +20,20 @@
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-
+<script src="app/vid/external/multiselect/angular-bootstrap-multiselect.min.js"></script>
<script src="app/vid/scripts/angular-ui-tree.js"></script>
+<script src="app/vid/external/lodash/lodash.min.js"></script>
<script src="app/vid/scripts/constants/componentConstants.js"></script>
<script src="app/vid/scripts/constants/fieldConstants.js"></script>
<script src="app/vid/scripts/constants/vidConfiguration.js"></script>
<script src="app/vid/scripts/constants/parameterConstants.js"></script>
+<script src="app/vid/scripts/filters/change-managements-by-statuses.filter.js"></script>
+<script src="app/vid/scripts/filters/date.filter.js"></script>
+<script src="app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.controller.js"></script>
+<script src="app/vid/scripts/modals/new-change-management/new-change-management.controller.js"></script>
+<script src="app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js"></script>
<script src="app/vid/scripts/controller/aaiSubscriberController.js"></script>
<script src="app/vid/scripts/controller/creationDialogController.js"></script>
<script src="app/vid/scripts/controller/deletionDialogController.js"></script>
@@ -35,11 +44,17 @@
<script src="app/vid/scripts/controller/ServiceModelController.js"></script>
<script src="app/vid/scripts/controller/previousVersionDialogController.js"></script>
<script src="app/vid/scripts/controller/previousVersionContoller.js"></script>
+<script src="app/vid/scripts/controller/change-management.controller.js"></script>
+
+<script src="app/vid/scripts/directives/angularjs-datetime-picker.js"></script>
+
+
<script src="app/vid/scripts/directives/extensionsDirective.js"></script>
<script src="app/vid/scripts/directives/parameterBlockDirective.js"></script>
<script src="app/vid/scripts/directives/popupWindowDirective.js"></script>
<script src="app/vid/scripts/directives/progressBarDirective.js"></script>
<script src="app/vid/scripts/services/aaiService.js"></script>
+<script src="app/vid/scripts/services/schedulerService.js"></script>
<script src="app/vid/scripts/services/asdcService.js"></script>
<script src="app/vid/scripts/services/componentService.js"></script>
<script src="app/vid/scripts/services/creationService.js"></script>
@@ -51,6 +66,7 @@
<script src="app/vid/scripts/services/propertyService.js"></script>
<script src="app/vid/scripts/services/utilityService.js"></script>
<script src="app/vid/scripts/services/vnfService.js"></script>
+<script src="app/vid/scripts/services/change-management.service.js"></script>
<%@ page import="org.openecomp.vid.mso.*"%>
<%@ page import="org.openecomp.portalsdk.core.util.SystemProperties"%>
diff --git a/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/welcome.jsp b/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/welcome.jsp
index 9cb6f85b7..ad5331d98 100755
--- a/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/welcome.jsp
+++ b/epsdk-app-onap/src/main/webapp/WEB-INF/jsp/welcome.jsp
@@ -1,4 +1,4 @@
-
+<script src="app/vid/external/multiselect/angular-bootstrap-multiselect.min.js"></script>
<div>
<h1 class="heading1">ONAP</h1>
<br>
diff --git a/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/app.js b/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/app.js
index 0787015bf..59e27470f 100755
--- a/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/app.js
+++ b/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/app.js
@@ -1,6 +1,5 @@
angular.module('att.abs.helper', []);
angular.module('quantum', []);
-angular.module('ui.bootstrap', []);
-var app=angular.module("abs", ["att.abs", "att.abs.helper","modalServices",
- "att.gridster","checklist-model","ngRoute", "ui.bootstrap","ngCookies"]);
+var app=angular.module("abs", ["att.abs", "att.abs.helper","modalServices", /*'ngAnimate','ngTouch',*/ 'ui.bootstrap',
+ "att.gridster","checklist-model","ngRoute", "ngCookies", 'btorfs.multiselect']);
diff --git a/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/appDS2.js b/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/appDS2.js
index 3a101934c..d982b7855 100755
--- a/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/appDS2.js
+++ b/epsdk-app-onap/src/main/webapp/app/fusion/external/ebz/angular_js/appDS2.js
@@ -1,5 +1,4 @@
angular.module('att.abs.helper', []);
angular.module('quantum', []);
-angular.module('ui.bootstrap', []);
-var appDS2=angular.module("abs", ["ngRoute", 'ngMessages', 'ngCookies', 'b2b.att.tpls', 'ddh.att.tpls', 'ddh.att.switches', 'b2b.att.footer', 'b2b.att.header']);
+var appDS2=angular.module("abs", ["ngRoute", /*'ngAnimate', 'ngTouch',*/ 'ui.bootstrap', 'ngMessages', 'ngCookies', 'b2b.att.tpls', 'ddh.att.tpls', 'ddh.att.switches', 'b2b.att.footer', 'b2b.att.header', 'btorfs.multiselect']);
var app = appDS2;
diff --git a/epsdk-app-onap/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js b/epsdk-app-onap/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js
new file mode 100644
index 000000000..b9be2c7e4
--- /dev/null
+++ b/epsdk-app-onap/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js
@@ -0,0 +1 @@
+!function(){"use strict";var a=angular.module("btorfs.multiselect",["btorfs.multiselect.templates"]);a.getRecursiveProperty=function(a,b){return b.split(".").reduce(function(a,b){return a?a[b]:null},a)},a.directive("multiselect",["$filter","$document","$log",function(b,c,d){return{restrict:"AE",scope:{options:"=",displayProp:"@",idProp:"@",searchLimit:"=?",selectionLimit:"=?",showSelectAll:"=?",showUnselectAll:"=?",showSearch:"=?",searchFilter:"=?",disabled:"=?ngDisabled",labels:"=?",showTooltip:"=?",placeholder:"@?"},require:"ngModel",templateUrl:"multiselect.html",link:function(b,e,f,g){b.selectionLimit=b.selectionLimit||0,b.searchLimit=b.searchLimit||25,b.searchFilter="",b.resolvedOptions=[],"function"!=typeof b.options&&(b.resolvedOptions=b.options),"undefined"!=typeof f.disabled&&(b.disabled=!0);var h=function(a){e[0].contains(a.target)||b.$apply(function(){b.open=!1})};c.on("click",h);var i=function(){g.$viewValue?(b.selectedOptions=b.resolvedOptions.filter(function(a){for(var c=b.getId(a),d=0;d<g.$viewValue.length;d++){var e=b.getId(g.$viewValue[d]);if(c===e)return!0}return!1}),b.unselectedOptions=b.resolvedOptions.filter(function(a){return b.selectedOptions.indexOf(a)<0})):(b.selectedOptions&&(b.selectedOptions=[]),b.unselectedOptions=b.resolvedOptions.slice())};b.toggleDropdown=function(){b.open=!b.open,b.resolvedOptions=b.options,i()},g.$render=function(){i()},g.$viewChangeListeners.push(function(){i()}),g.$isEmpty=function(a){return!a||0===a.length};var j=b.$watch("selectedOptions",function(){g.$setViewValue(angular.copy(b.selectedOptions))},!0);b.$on("$destroy",function(){c.off("click",h),j&&j()}),b.getButtonText=function(){if(b.selectedOptions&&1===b.selectedOptions.length)return b.getDisplay(b.selectedOptions[0]);if(b.selectedOptions&&b.selectedOptions.length>1){var a=angular.isDefined(b.selectedOptions)?b.selectedOptions.length:0;return 0===a?b.labels&&b.labels.select?b.labels.select:b.placeholder||"Select":a+" "+(b.labels&&b.labels.itemsSelected?b.labels.itemsSelected:"selected")}return b.labels&&b.labels.select?b.labels.select:b.placeholder||"Select"},b.selectAll=function(){b.selectedOptions=b.resolvedOptions.slice(),b.unselectedOptions=[]},b.unselectAll=function(){b.selectedOptions=[],b.unselectedOptions=b.resolvedOptions.slice()},b.toggleItem=function(a){"undefined"==typeof b.selectedOptions&&(b.selectedOptions=[]);var c=b.selectedOptions.indexOf(a),d=c!==-1;if(d)b.unselectedOptions.push(b.selectedOptions[c]),b.selectedOptions.splice(c,1);else if(!d&&(0===b.selectionLimit||b.selectedOptions.length<b.selectionLimit)){var e=b.unselectedOptions.indexOf(a);b.unselectedOptions.splice(e,1),b.selectedOptions.push(a)}},b.getId=function(c){return angular.isString(c)?c:angular.isObject(c)?b.idProp?a.getRecursiveProperty(c,b.idProp):(d.error("Multiselect: when using objects as model, a idProp value is mandatory."),""):c},b.getDisplay=function(c){return angular.isString(c)?c:angular.isObject(c)?b.displayProp?a.getRecursiveProperty(c,b.displayProp):(d.error("Multiselect: when using objects as model, a displayProp value is mandatory."),""):c},b.isSelected=function(a){if(!b.selectedOptions)return!1;for(var c=b.getId(a),d=0;d<b.selectedOptions.length;d++){var e=b.selectedOptions[d];if(b.getId(e)===c)return!0}return!1},b.updateOptions=function(){"function"==typeof b.options&&b.options().then(function(a){b.resolvedOptions=a,i()})},b.search=function(){var a=0;return function(c){if(a>b.searchLimit)return!1;var d=b.getDisplay(c);if(d){var e=d.toLowerCase().indexOf(b.searchFilter.toLowerCase())>-1;return e&&a++,e}}}}}}])}(),angular.module("btorfs.multiselect.templates",["multiselect.html"]),angular.module("multiselect.html",[]).run(["$templateCache",function(a){a.put("multiselect.html",'<div class="btn-group" style="width: 100%">\n <button type="button" class="btn btn-default btn-block dropdown-toggle" ng-click="toggleDropdown()" ng-disabled="disabled" style="white-space: nowrap; overflow-x: hidden; text-overflow: ellipsis;">\n {{getButtonText()}}&nbsp;<span class="caret"></span>\n </button>\n <ul class="dropdown-menu dropdown-menu-form"\n ng-style="{display: open ? \'block\' : \'none\'}" style="width: 100%; overflow-x: auto">\n\n <li ng-show="showSelectAll">\n <a ng-click="selectAll()" href="">\n <span class="glyphicon glyphicon-ok"></span> {{labels.selectAll || \'Select All\'}}\n </a>\n </li>\n <li ng-show="showUnselectAll">\n <a ng-click="unselectAll()" href="">\n <span class="glyphicon glyphicon-remove"></span> {{labels.unselectAll || \'Unselect All\'}}\n </a>\n </li>\n <li ng-show="(showSelectAll || showUnselectAll)"\n class="divider">\n </li>\n\n <li role="presentation" ng-repeat="option in selectedOptions" class="active">\n <a class="item-selected" href="" title="{{showTooltip ? getDisplay(option) : \'\'}}" ng-click="toggleItem(option); $event.stopPropagation()" style="overflow-x: auto">\n <span class="glyphicon glyphicon-remove"></span>\n {{getDisplay(option)}}\n </a>\n </li>\n <li ng-show="selectedOptions.length > 0" class="divider"></li>\n\n <li ng-show="showSearch">\n <div class="dropdown-header">\n <input type="text" class="form-control input-sm" style="width: 100%;"\n ng-model="searchFilter" placeholder="{{labels.search || \'Search...\'}}" ng-change="updateOptions()"/>\n </div>\n </li>\n\n <li ng-show="showSearch" class="divider"></li>\n <li role="presentation" ng-repeat="option in unselectedOptions | filter:search() | limitTo: searchLimit"\n ng-if="!isSelected(option)"\n ng-class="{disabled : selectionLimit && selectedOptions.length >= selectionLimit}">\n <a class="item-unselected" href="" title="{{showTooltip ? getDisplay(option) : \'\'}}" ng-click="toggleItem(option); $event.stopPropagation()" style="overflow-x: auto">\n {{getDisplay(option)}}\n </a>\n </li>\n\n <li class="divider" ng-show="selectionLimit > 1"></li>\n <li role="presentation" ng-show="selectionLimit > 1">\n <a>{{selectedOptions.length || 0}} / {{selectionLimit}} {{labels.itemsSelected || \'selected\'}}</a>\n </li>\n\n </ul>\n</div>\n')}]); \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/aai/util/AAIRestInterface.java b/vid-app-common/src/main/java/org/openecomp/aai/util/AAIRestInterface.java
index 243410050..d9bb5c1f4 100755
--- a/vid-app-common/src/main/java/org/openecomp/aai/util/AAIRestInterface.java
+++ b/vid-app-common/src/main/java/org/openecomp/aai/util/AAIRestInterface.java
@@ -253,6 +253,54 @@ public class AAIRestInterface {
return false;
}
+
+ /**
+ * Rest put.
+ *
+ * @param fromAppId the from app id
+ * @param transId the trans id
+ * @param path the path
+ * @param payload the payload
+ * @param xml the xml
+ * @return the string
+ */
+ public Response RestPut(String fromAppId, String transId, String path, String payload, boolean xml) {
+ String methodName = "RestPost";
+ String url="";
+ transId = UUID.randomUUID().toString();
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+
+ String responseType = "application/json";
+ if (xml)
+ responseType = "application/xml";
+
+ initRestClient();
+
+ url = SystemProperties.getProperty(AAIProperties.AAI_SERVER_URL) + path;
+
+ final Response cres = client.target(url)
+ .request()
+ .accept(responseType)
+ .header("X-TransactionId", transId)
+ .header("X-FromAppId", fromAppId)
+ .put(Entity.entity(payload, MediaType.APPLICATION_JSON));
+
+ if (cres.getStatus() == 200 && cres.getStatus() <= 299) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+ } else {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName +" with status="+cres.getStatus()+", url="+url);
+ }
+ return cres;
+ } catch (Exception e) {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ }
+ return null;
+ }
+
+
/**
* Rest post.
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/RelatedTo.java b/vid-app-common/src/main/java/org/openecomp/vid/RelatedTo.java
new file mode 100644
index 000000000..48ca49705
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/RelatedTo.java
@@ -0,0 +1,36 @@
+package org.openecomp.vid;
+
+import com.fasterxml.jackson.annotation.*;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "id",
+ "node-type",
+ "url"
+})
+public class RelatedTo {
+
+ @JsonProperty("id")
+ public String id;
+ @JsonProperty("node-type")
+ public String nodeType;
+ @JsonProperty("url")
+ public String url;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClient.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClient.java
index af1f4042a..0f07f2066 100644
--- a/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClient.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClient.java
@@ -7,9 +7,8 @@ import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.openecomp.aai.util.AAIRestInterface;
-import org.apache.tiles.request.ApplicationContext;
import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
-import org.openecomp.portalsdk.core.web.support.UserUtils;
+import org.openecomp.vid.aai.model.ServiceRelationships;
import org.openecomp.vid.aai.model.AaiGetServicesRequestModel.GetServicesAAIRespone;
import org.openecomp.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.openecomp.vid.model.SubscriberList;
@@ -25,6 +24,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
+import java.util.List;
import java.util.UUID;
@@ -33,252 +33,320 @@ import java.util.UUID;
*/
public class AaiClient implements AaiClientInterface {
- /**
- * The Constant dateFormat.
- */
- final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
- protected String fromAppId = "VidAaiController";
- @Autowired
- ServletContext servletContext;
- /**
- * The logger
- */
-
- EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiClient.class);
-
-
- public AaiClient() {
- // certiPath = getCertificatesFile().getAbsolutePath();
- // depth = "0";
- }
-
- public AaiClient(ServletContext context) {
- servletContext = context;
- }
-
-
-
- private static String checkForNull(String local) {
- if (local != null)
- return local;
- else
- return "";
-
- }
-
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+ protected String fromAppId = "VidAaiController";
+ @Autowired
+ ServletContext servletContext;
+ /**
+ * The logger
+ */
+
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiClient.class);
+
+
+ public AaiClient() {
+ // certiPath = getCertificatesFile().getAbsolutePath();
+ // depth = "0";
+ }
+
+ public AaiClient(ServletContext context) {
+ servletContext = context;
+ }
+
+
+ private static String checkForNull(String local) {
+ if (local != null)
+ return local;
+ else
+ return "";
+
+ }
+
+ @Override
+ public AaiResponse<SubscriberList> getAllSubscribers() {
+ String certiPath = getCertificatesFile().getAbsolutePath();
+ String depth = "0";
+ Response resp = doAaiGet(certiPath, "business/customers?subscriber-type=INFRA&depth=" + depth, false);
+ return proccessAaiResponse(resp, SubscriberList.class, null);
+ }
+
+
+ @Override
+ public AaiResponse getAllAicZones() {
+ String certiPath = getCertificatesFile().getAbsolutePath();
+ Response resp = doAaiGet(certiPath, "network/zones", false);
+ AaiResponse aaiAicZones = proccessAaiResponse(resp, AicZones.class, null);
+ return aaiAicZones;
+ }
+
+
@Override
- public AaiResponse<SubscriberList> getAllSubscribers() {
+ public AaiResponse<String> getAicZoneForPnf(String globalCustomerId , String serviceType , String serviceId) {
String certiPath = getCertificatesFile().getAbsolutePath();
- String depth = "0";
- Response resp = doAaiGet(certiPath, "business/customers?subscriber-type=INFRA&depth=" + depth, false);
- UserUtils userUtils = new UserUtils();
- return proccessAaiResponse(resp, SubscriberList.class,null);
- }
-
-
- @Override
- public AaiResponse getAllAicZones() {
- String certiPath = getCertificatesFile().getAbsolutePath();
- Response resp = doAaiGet(certiPath, "network/zones" , false);
- AaiResponse aaiAicZones = proccessAaiResponse(resp, AicZones.class,null);
- return aaiAicZones;
- }
-
- @Override
- public AaiResponse getSubscriberData(String subscriberId) {
-
- File certiPath = getCertificatesFile();
- String depth = "2";
- AaiResponse subscriberDataResponse;
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + subscriberId + "?depth=" + depth, false);
- subscriberDataResponse = proccessAaiResponse(resp, Services.class,null);
- return subscriberDataResponse;
- }
-
- @Override
- public AaiResponse getServices() {
- File certiPath = getCertificatesFile();
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "service-design-and-creation/services", false);
- AaiResponse<GetServicesAAIRespone> getServicesResponse = proccessAaiResponse(resp, GetServicesAAIRespone.class,null);
-
- return getServicesResponse;
+ String aicZonePath = "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + serviceType + "/service-instances/service-instance/" + serviceId;
+ Response resp = doAaiGet(certiPath , aicZonePath , false);
+ AaiResponse<ServiceRelationships> aaiResponse = proccessAaiResponse(resp , ServiceRelationships.class , null);
+ ServiceRelationships serviceRelationships = (ServiceRelationships)aaiResponse.getT();
+ String aicZone = serviceRelationships.getRelationshipList().getRelationship().get(0).getRelatedToPropertyList().get(0).getPropertyValue();
+ AaiResponse<String> aaiAicZonaForPnfResponse = new AaiResponse(aicZone , null ,HttpStatus.SC_OK);
+ return aaiAicZonaForPnfResponse;
}
+
+
+ @Override
+ public AaiResponse getVNFData() {
+ String certiPath = getCertificatesFile().getAbsolutePath();
+ String payload = "{\"start\": [\"/business/customers/customer/e433710f-9217-458d-a79d-1c7aff376d89/service-subscriptions/service-subscription/VIRTUAL%20USP/service-instances/service-instance/3f93c7cb-2fd0-4557-9514-e189b7b04f9d\"], \"query\": \"query/vnf-topology-fromServiceInstance\"}";
+ Response resp = doAaiPut(certiPath, "query?format=simple", payload, false);
+ return proccessAaiResponse(resp, AaiGetVnfResponse.class, null);
+
+ }
+
+ @Override
+ public Response getVNFData(String globalSubscriberId, String serviceType) {
+ String certiPath = getCertificatesFile().getAbsolutePath();
+ String payload = "{\"start\": [\"business/customers/customer/" + globalSubscriberId + "/service-subscriptions/service-subscription/"+ serviceType +"/service-instances\"]," +
+ "\"query\": \"query/vnf-topology-fromServiceInstance\"}";
+ return doAaiPut(certiPath, "query?format=simple", payload, false);
+
+ }
+
+ @Override
+ public AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId) {
+ String certiPath = getCertificatesFile().getAbsolutePath();
+ String payload = "{\"start\": [\"/business/customers/customer/" + globalSubscriberId + "/service-subscriptions/service-subscription/" + serviceType + "/service-instances/service-instance/" + serviceInstanceId + "\"], \"query\": \"query/vnf-topology-fromServiceInstance\"}";
+ Response resp = doAaiPut(certiPath, "query?format=simple", payload, false);
+ return proccessAaiResponse(resp, AaiGetVnfResponse.class, null);
+ }
+
+ @Override
+ public Response getVersionByInvariantId(List<String> modelInvariantId) {
+ File certiPath = getCertificatesFile();
+ StringBuilder sb = new StringBuilder();
+ for (String id : modelInvariantId){
+ sb.append("&model-invariant-id=");
+ sb.append(id);
+
+ }
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "service-design-and-creation/models?depth=2"+ sb.toString(), false);
+ return resp;
+ }
+
+ @Override
+ public AaiResponse getSubscriberData(String subscriberId) {
+ File certiPath = getCertificatesFile();
+ String depth = "2";
+ AaiResponse subscriberDataResponse;
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + subscriberId + "?depth=" + depth, false);
+ subscriberDataResponse = proccessAaiResponse(resp, Services.class, null);
+ return subscriberDataResponse;
+ }
+
+ @Override
+ public AaiResponse getServices() {
+ File certiPath = getCertificatesFile();
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "service-design-and-creation/services", false);
+ AaiResponse<GetServicesAAIRespone> getServicesResponse = proccessAaiResponse(resp, GetServicesAAIRespone.class, null);
+
+ return getServicesResponse;
+ }
+
+ @Override
+ public AaiResponse getTenants(String globalCustomerId, String serviceType) {
+ File certiPath = getCertificatesFile();
+ String url = "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + serviceType;
+
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), url, false);
+ String responseAsString = parseForTenantsByServiceSubscription(resp.readEntity(String.class));
+
+ AaiResponse<GetTenantsResponse[]> getTenantsResponse = proccessAaiResponse(resp, GetTenantsResponse[].class, responseAsString);
+ return getTenantsResponse;
+ }
+
+ private AaiResponse proccessAaiResponse(Response resp, Class classType, String responseBody) {
+ AaiResponse subscriberDataResponse;
+ if (resp == null) {
+ subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
+ } else {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscribers() resp=" + resp.getStatusInfo().toString());
+ if (resp.getStatus() != HttpStatus.SC_OK) {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
+ subscriberDataResponse = new AaiResponse<>(null, resp.readEntity(String.class), resp.getStatus());
+ } else {
+ String finalResponse;
+ try {
+ if (responseBody != null) {
+ finalResponse = responseBody;
+ } else {
+ finalResponse = resp.readEntity(String.class);
+ }
+
+ subscriberDataResponse = new AaiResponse<>((new ObjectMapper().readValue(finalResponse, classType)), null, HttpStatus.SC_OK);
+
+ } catch (IOException e) {
+ subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
+ }
+
+ }
+ }
+ return subscriberDataResponse;
+ }
+
+ private File getCertificatesFile() {
+ if (servletContext != null)
+ return new File(servletContext.getRealPath("/WEB-INF/cert/"));
+ return null;
+ }
+
+ @SuppressWarnings("all")
+ protected Response doAaiGet(String certiPath, String uri, boolean xml) {
+ String methodName = "doAaiGet";
+ String transId = UUID.randomUUID().toString();
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ Response resp = null;
+ try {
+
+ AAIRestInterface restContrller = new AAIRestInterface(certiPath);
+ resp = restContrller.RestGet(fromAppId, transId, uri, xml);
+
+ } catch (WebApplicationException e) {
+ final String message = ((BadRequestException) e).getResponse().readEntity(String.class);
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ }
+
+ return resp;
+ }
+
+ private String parseForTenantsByServiceSubscription(String resp) {
+ String tenantList = "";
+
+ try {
+ JSONParser jsonParser = new JSONParser();
+
+ JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
+
+ return parseServiceSubscriptionObjectForTenants(jsonObject);
+ } catch (Exception ex) {
+
+ }
+
+ return tenantList;
+ }
+
+ protected Response doAaiPut(String certiPath, String uri, String payload, boolean xml) {
+ String methodName = "doAaiPut";
+ String transId = UUID.randomUUID().toString();
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ Response resp = null;
+ try {
- @Override
- public AaiResponse getTenants(String globalCustomerId, String serviceType) {
- File certiPath = getCertificatesFile();
- String url = "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + serviceType;
-
- Response resp = doAaiGet(certiPath.getAbsolutePath(), url, false);
- String responseAsString = parseForTenantsByServiceSubscription(resp.readEntity(String.class));
-
- AaiResponse<GetTenantsResponse[]> getTenantsResponse = proccessAaiResponse(resp, GetTenantsResponse[].class,responseAsString);
- return getTenantsResponse;
- }
-
- private AaiResponse proccessAaiResponse(Response resp, Class classType,String responseBody) {
- AaiResponse subscriberDataResponse;
- if (resp == null) {
- subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
- } else {
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscribers() resp=" + resp.getStatusInfo().toString());
- if (resp.getStatus() != HttpStatus.SC_OK) {
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "Invalid response from AAI");
- subscriberDataResponse = new AaiResponse<>(null, resp.readEntity(String.class), resp.getStatus());
- } else {
- String finalResponse;
- try {
- if (responseBody != null){
- finalResponse = responseBody;
- }
- else{
- finalResponse = resp.readEntity(String.class);;
- }
-
- subscriberDataResponse = new AaiResponse<>((new ObjectMapper().readValue(finalResponse, classType)), null, HttpStatus.SC_OK);
-
- } catch (IOException e) {
- subscriberDataResponse = new AaiResponse<>(null, null, HttpStatus.SC_INTERNAL_SERVER_ERROR);
- }
-
- }
- }
- return subscriberDataResponse;
- }
-
- private File getCertificatesFile() {
- if (servletContext != null)
- return new File(servletContext.getRealPath("/WEB-INF/cert/"));
- return null;
- }
-
- @SuppressWarnings("all")
- protected Response doAaiGet(String certiPath, String uri, boolean xml) {
- String methodName = "getSubscriberList";
- String transId = UUID.randomUUID().toString();
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
-
- Response resp = null;
- try {
-
- AAIRestInterface restContrller = new AAIRestInterface(certiPath);
- resp = restContrller.RestGet(fromAppId, transId, uri, xml);
-
- } catch (WebApplicationException e) {
- final String message = ((BadRequestException) e).getResponse().readEntity(String.class);
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- }
-
- return resp;
- }
-
- private String parseForTenantsByServiceSubscription(String resp) {
- String tenantList = "";
-
- try {
- JSONParser jsonParser = new JSONParser();
-
- JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
-
- return parseServiceSubscriptionObjectForTenants(jsonObject);
- } catch (Exception ex) {
-
- }
-
- return tenantList;
- }
+ AAIRestInterface restContrller = new AAIRestInterface(certiPath);
+ resp = restContrller.RestPut(fromAppId, transId, uri, payload, xml);
+
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ }
+
+ return resp;
+ }
+ public static String parseServiceSubscriptionObjectForTenants(JSONObject jsonObject) {
+
+ JSONArray tenantArray = new JSONArray();
+ boolean bconvert = false;
+
+ try {
+ JSONObject relationShipListsObj = (JSONObject) jsonObject.get("relationship-list");
+ if (relationShipListsObj != null) {
+ JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
+ if (rShipArray != null) {
+ Iterator i1 = rShipArray.iterator();
- public static String parseServiceSubscriptionObjectForTenants(JSONObject jsonObject) {
+ while (i1.hasNext()) {
- JSONArray tenantArray = new JSONArray();
- boolean bconvert = false;
+ JSONObject inner1Obj = (JSONObject) i1.next();
- try {
- JSONObject relationShipListsObj = (JSONObject) jsonObject.get("relationship-list");
- if (relationShipListsObj != null) {
- JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
- if (rShipArray != null) {
- Iterator i1 = rShipArray.iterator();
+ if (inner1Obj == null)
+ continue;
- while (i1.hasNext()) {
+ String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
+ if (relatedTo.equalsIgnoreCase("tenant")) {
+ JSONObject tenantNewObj = new JSONObject();
- JSONObject inner1Obj = (JSONObject) i1.next();
+ String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
+ tenantNewObj.put("link", relatedLink);
- if (inner1Obj == null)
- continue;
+ JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
+ if (rDataArray != null) {
+ Iterator i2 = rDataArray.iterator();
- String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
- if (relatedTo.equalsIgnoreCase("tenant")) {
- JSONObject tenantNewObj = new JSONObject();
+ while (i2.hasNext()) {
+ JSONObject inner2Obj = (JSONObject) i2.next();
- String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
- tenantNewObj.put("link", relatedLink);
+ if (inner2Obj == null)
+ continue;
- JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
- if (rDataArray != null) {
- Iterator i2 = rDataArray.iterator();
+ String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
+ String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
+ if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
+ tenantNewObj.put("cloudOwner", rShipVal);
+ } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
+ tenantNewObj.put("cloudRegionID", rShipVal);
+ }
- while (i2.hasNext()) {
- JSONObject inner2Obj = (JSONObject) i2.next();
+ if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
+ tenantNewObj.put("tenantID", rShipVal);
+ }
+ }
+ }
- if (inner2Obj == null)
- continue;
+ JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
+ if (relatedTPropArray != null) {
+ Iterator i3 = relatedTPropArray.iterator();
- String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
- String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
- if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
- tenantNewObj.put("cloudOwner", rShipVal);
- } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
- tenantNewObj.put("cloudRegionID", rShipVal);
- }
+ while (i3.hasNext()) {
+ JSONObject inner3Obj = (JSONObject) i3.next();
- if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
- tenantNewObj.put("tenantID", rShipVal);
- }
- }
- }
+ if (inner3Obj == null)
+ continue;
- JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
- if (relatedTPropArray != null) {
- Iterator i3 = relatedTPropArray.iterator();
+ String propKey = checkForNull((String) inner3Obj.get("property-key"));
+ String propVal = checkForNull((String) inner3Obj.get("property-value"));
+ if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
+ tenantNewObj.put("tenantName", propVal);
+ }
+ }
+ }
+ bconvert = true;
+ tenantArray.add(tenantNewObj);
+ }
+ }
- while (i3.hasNext()) {
- JSONObject inner3Obj = (JSONObject) i3.next();
+ }
+ }
+ } catch (NullPointerException ex) {
- if (inner3Obj == null)
- continue;
- String propKey = checkForNull((String) inner3Obj.get("property-key"));
- String propVal = checkForNull((String) inner3Obj.get("property-value"));
- if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
- tenantNewObj.put("tenantName", propVal);
- }
- }
- }
- bconvert = true;
- tenantArray.add(tenantNewObj);
- }
- }
+ }
- }
- }
- } catch (NullPointerException ex) {
+ if (bconvert)
+ return tenantArray.toJSONString();
+ else
+ return "";
+ }
- }
-
- if (bconvert)
- return tenantArray.toJSONString();
- else
- return "";
-
- }
} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClientInterface.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClientInterface.java
index fdaf602f4..f1b1ba2df 100644
--- a/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClientInterface.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiClientInterface.java
@@ -3,6 +3,7 @@ package org.openecomp.vid.aai;
import org.openecomp.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.openecomp.vid.model.SubscriberList;
+import javax.ws.rs.core.Response;
import java.util.List;
/**
@@ -19,4 +20,14 @@ public interface AaiClientInterface {
AaiResponse<GetTenantsResponse[]> getTenants(String globalCustomerId, String serviceType);
AaiResponse getAllAicZones();
+
+ AaiResponse getAicZoneForPnf(String globalCustomerId , String serviceType , String serviceId);
+
+ AaiResponse getVNFData();
+
+ Response getVNFData(String globalSubscriberId, String serviceType);
+
+ AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId);
+
+ Response getVersionByInvariantId(List<String> modelInvariantId);
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiGetVnfResponse.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiGetVnfResponse.java
new file mode 100644
index 000000000..7c9d44b12
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/AaiGetVnfResponse.java
@@ -0,0 +1,28 @@
+package org.openecomp.vid.aai;
+
+import com.fasterxml.jackson.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "results"
+})
+public class AaiGetVnfResponse {
+ @JsonProperty("results")
+ public List<VnfResult> results = null;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/ServiceProperties.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/ServiceProperties.java
new file mode 100644
index 000000000..113f113d3
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/ServiceProperties.java
@@ -0,0 +1,90 @@
+package org.openecomp.vid.aai;
+
+import com.fasterxml.jackson.annotation.*;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "service-instance-id",
+ "service-instance-name",
+ "model-invariant-id",
+ "model-version-id",
+ "resource-version",
+ "orchestration-status",
+ "global-customer-id",
+ "subscriber-name",
+ "subscriber-type",
+ "vnf-id",
+ "vnf-name",
+ "vnf-type",
+ "service-id",
+ "prov-status",
+ "in-maint",
+ "is-closed-loop-disabled",
+ "model-customization-id",
+ "nf-type",
+ "nf-function",
+ "nf-role",
+ "nf-naming-code"
+})
+public class ServiceProperties {
+
+ @JsonProperty("service-instance-id")
+ public String serviceInstanceId;
+ @JsonProperty("service-instance-name")
+ public String serviceInstanceName;
+ @JsonProperty("model-invariant-id")
+ public String modelInvariantId;
+ @JsonProperty("model-version-id")
+ public String modelVersionId;
+ @JsonProperty("resource-version")
+ public String resourceVersion;
+ @JsonProperty("orchestration-status")
+ public String orchestrationStatus;
+ @JsonProperty("global-customer-id")
+ public String globalCustomerId;
+ @JsonProperty("subscriber-name")
+ public String subscriberName;
+ @JsonProperty("subscriber-type")
+ public String subscriberType;
+ @JsonProperty("vnf-id")
+ public String vnfId;
+ @JsonProperty("vnf-name")
+ public String vnfName;
+ @JsonProperty("vnf-type")
+ public String vnfType;
+ @JsonProperty("service-id")
+ public String serviceId;
+ @JsonProperty("prov-status")
+ public String provStatus;
+ @JsonProperty("in-maint")
+ public Boolean inMaint;
+ @JsonProperty("is-closed-loop-disabled")
+ public Boolean isClosedLoopDisabled;
+ @JsonProperty("model-customization-id")
+ public String modelCustomizationId;
+ @JsonProperty("nf-type")
+ public String nfType;
+ @JsonProperty("nf-function")
+ public String nfFunction;
+ @JsonProperty("nf-role")
+ public String nfRole;
+ @JsonProperty("nf-naming-code")
+ public String nfNamingCode;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/VnfResult.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/VnfResult.java
new file mode 100644
index 000000000..b8294e519
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/VnfResult.java
@@ -0,0 +1,44 @@
+package org.openecomp.vid.aai;
+
+import com.fasterxml.jackson.annotation.*;
+import org.codehaus.jackson.annotate.JsonProperty;
+import org.openecomp.vid.RelatedTo;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "id",
+ "node-type",
+ "url",
+ "properties",
+ "related-to"
+})
+public class VnfResult {
+
+ @JsonProperty("id")
+ public String id;
+ @JsonProperty("node-type")
+ public String nodeType;
+ @JsonProperty("url")
+ public String url;
+ @JsonProperty("properties")
+ public ServiceProperties properties;
+ @JsonProperty("related-to")
+ public List<RelatedTo> relatedTo = null;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelatedToProperty.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelatedToProperty.java
new file mode 100644
index 000000000..c9f28ed69
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelatedToProperty.java
@@ -0,0 +1,34 @@
+package org.openecomp.vid.aai.model;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class RelatedToProperty {
+
+ public String getPropertyKey() {
+ return propertyKey;
+ }
+
+
+ public void setPropertyKey(String propertyKey) {
+ this.propertyKey = propertyKey;
+ }
+
+
+ public String getPropertyValue() {
+ return propertyValue;
+ }
+
+
+ public void setPropertyValue(String propertyValue) {
+ this.propertyValue = propertyValue;
+ }
+
+
+ @JsonProperty("property-key")
+ public String propertyKey;
+
+
+ @JsonProperty("property-value")
+ public String propertyValue;
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/model/Relationship.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/Relationship.java
new file mode 100644
index 000000000..796094192
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/Relationship.java
@@ -0,0 +1,55 @@
+package org.openecomp.vid.aai.model;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class Relationship {
+
+ @JsonProperty("related-to")
+ public String relatedTo;
+
+ @JsonProperty("related-link")
+ public String relatedLink;
+
+ @JsonProperty("relationship-data")
+ public List<RelationshipData> relationshipData;
+
+ @JsonProperty("related-to-property")
+ public List<RelatedToProperty> relatedToProperty;
+
+
+ public String getRelatedTo() {
+ return relatedTo;
+ }
+
+ public void setRelatedTo(String relatedTo) {
+ this.relatedTo = relatedTo;
+ }
+
+ public String getRelatedLink() {
+ return relatedLink;
+ }
+
+ public void setRelatedLink(String relatedLink) {
+ this.relatedLink = relatedLink;
+ }
+
+ public List<RelationshipData> getRelationDataList() {
+ return relationshipData;
+ }
+
+ public void setRelationDataList(List<RelationshipData> relationDataList) {
+ this.relationshipData = relationDataList;
+ }
+
+ public List<RelatedToProperty> getRelatedToPropertyList() {
+ return relatedToProperty;
+ }
+
+ public void setRelatedToPropertyList(List<RelatedToProperty> relatedToPropertyList) {
+ this.relatedToProperty = relatedToPropertyList;
+ }
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipData.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipData.java
new file mode 100644
index 000000000..21af2f5d6
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipData.java
@@ -0,0 +1,29 @@
+package org.openecomp.vid.aai.model;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class RelationshipData {
+
+ public String getRelationshipKey() {
+ return relationshipKey;
+ }
+
+ public void setRelationshipKey(String relationshipKey) {
+ this.relationshipKey = relationshipKey;
+ }
+
+ public String getRelationshipValue() {
+ return relationshipValue;
+ }
+
+ public void setRelationshipValue(String relationshipValue) {
+ this.relationshipValue = relationshipValue;
+ }
+
+ @JsonProperty("relationship-key")
+ public String relationshipKey;
+
+ @JsonProperty("relationship-value")
+ public String relationshipValue;
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipList.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipList.java
new file mode 100644
index 000000000..cdb7af46b
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/RelationshipList.java
@@ -0,0 +1,24 @@
+package org.openecomp.vid.aai.model;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class RelationshipList {
+
+
+ public List<Relationship> getRelationship() {
+ return relationship;
+ }
+
+ public void setRelationship(List<Relationship> relationship) {
+ this.relationship = relationship;
+ }
+
+ @JsonProperty("relationship")
+ public List<Relationship> relationship;
+
+
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/aai/model/ServiceRelationships.java b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/ServiceRelationships.java
new file mode 100644
index 000000000..9bedd8545
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/aai/model/ServiceRelationships.java
@@ -0,0 +1,90 @@
+package org.openecomp.vid.aai.model;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+public class ServiceRelationships {
+
+ @JsonProperty("service-instance-id")
+ public String serviceInstanceId;
+
+ @JsonProperty("service-instance-name")
+ public String serviceInstanceName;
+
+ @JsonProperty("model-invariant-id")
+ public String modelInvariantId;
+
+ @JsonProperty("model-version-id")
+ public String modelVersionId;
+
+ @JsonProperty("resource-version")
+ public String resourceVersion;
+
+ @JsonProperty("orchestration-status")
+ public String orchestrationStatus;
+
+ @JsonProperty("relationship-list")
+ public RelationshipList relationshipList;
+
+
+ public String getServiceInstanceId() {
+ return serviceInstanceId;
+ }
+
+ public void setServiceInstanceId(String serviceInstanceId) {
+ this.serviceInstanceId = serviceInstanceId;
+ }
+
+ public String getServiceInstanceName() {
+ return serviceInstanceName;
+ }
+
+ public void setServiceInstanceName(String serviceInstanceName) {
+ this.serviceInstanceName = serviceInstanceName;
+ }
+
+ public String getModelInvariantId() {
+ return modelInvariantId;
+ }
+
+ public void setModelInvariantId(String modelInvariantId) {
+ this.modelInvariantId = modelInvariantId;
+ }
+
+ public String getModelVersionId() {
+ return modelVersionId;
+ }
+
+ public void setModelVersionId(String modelVersionId) {
+ this.modelVersionId = modelVersionId;
+ }
+
+ public String getResourceVersion() {
+ return resourceVersion;
+ }
+
+ public void setResourceVersion(String resourceVersion) {
+ this.resourceVersion = resourceVersion;
+ }
+
+ public String getOrchestrationStatus() {
+ return orchestrationStatus;
+ }
+
+ public void setOrchestrationStatus(String orchestrationStatus) {
+ this.orchestrationStatus = orchestrationStatus;
+ }
+
+ public RelationshipList getRelationshipList() {
+ return relationshipList;
+ }
+
+ public void setRelationshipList(RelationshipList relationshipList) {
+ this.relationshipList = relationshipList;
+ }
+
+
+
+
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/asdc/beans/tosca/ToscaMetadata.java b/vid-app-common/src/main/java/org/openecomp/vid/asdc/beans/tosca/ToscaMetadata.java
index 41c7ca5ba..d42c1f150 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/asdc/beans/tosca/ToscaMetadata.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/asdc/beans/tosca/ToscaMetadata.java
@@ -61,9 +61,6 @@ public class ToscaMetadata {
/** The resource vendor release. */
private String resourceVendorRelease;
- /** the resourceVendorModelNumber */
- private String resourceVendorModelNumber;
-
/** The service ecomp naming. */
private String serviceEcompNaming;
@@ -91,11 +88,6 @@ public class ToscaMetadata {
/** The vf module model version. */
private String vfModuleModelVersion;
-
- /** serviceType */
- private String serviceType;
- /** serviceRole */
- private String serviceRole;
/**
* Instantiates a new tosca metadata.
@@ -466,26 +458,4 @@ public class ToscaMetadata {
return vfModuleModelCustomizationUUID;
}
-
- /** serviceType */
- public String getServiceType() {
- return serviceType;
- }
- public void setServiceType(String serviceType) {
- this.serviceType= serviceType;
- }
- /** serviceRole */
- public String getServiceRole() {
- return serviceRole;
- }
- public void setServiceRole(String serviceRole) {
- this.serviceRole= serviceRole;
- }
- /** resourceVendorModelNumber */
- public String getResourceVendorModelNumber() {
- return resourceVendorModelNumber;
- }
- public void setResourceVendorModelNumber(String resourceVendorModelNumber) {
- this.resourceVendorModelNumber= resourceVendorModelNumber;
- }
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/asdc/parser/ToscaParserImpl2.java b/vid-app-common/src/main/java/org/openecomp/vid/asdc/parser/ToscaParserImpl2.java
index 3f0dd8c31..e2b32fa8c 100644
--- a/vid-app-common/src/main/java/org/openecomp/vid/asdc/parser/ToscaParserImpl2.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/asdc/parser/ToscaParserImpl2.java
@@ -191,6 +191,8 @@ public class ToscaParserImpl2 {
volumeGroup.setModelCustomizationName(group.getMetadata().getValue(Constants.vfModuleModelName));
volumeGroup.setVersion(group.getMetadata().getValue(Constants.vfModuleModelVersion));
volumeGroup.setUuid(group.getMetadata().getValue(Constants.vfModuleModelUUID));
+ volumeGroup.setCustomizationUuid(group.getMetadata().getValue(Constants.vfModuleModelCustomizationUUID));
+
return volumeGroup;
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementRequest.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementRequest.java
new file mode 100644
index 000000000..adcb54683
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementRequest.java
@@ -0,0 +1,63 @@
+package org.openecomp.vid.changeManagement;
+
+import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonPropertyOrder({
+ "requestDetails",
+ "requestType"
+})
+
+public class ChangeManagementRequest {
+
+ public ChangeManagementRequest() {}
+
+ @JsonProperty("requestDetails")
+ private List<RequestDetails> requestDetails;
+
+ @JsonProperty("requestType")
+ private String requestType;
+
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonProperty("requestDetails")
+ public List<RequestDetails> getRequestDetails() {
+ return requestDetails;
+ }
+
+ @JsonProperty("requestDetails")
+ public void setRequestDetails(List<RequestDetails> requestDetails) {
+ this.requestDetails = requestDetails;
+ }
+
+ @JsonProperty("requestType")
+ public String getRequestType() {
+ return requestType;
+ }
+
+ @JsonProperty("requestType")
+ public void setRequestType(String requestType) {
+ this.requestType = requestType;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementResponse.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementResponse.java
new file mode 100644
index 000000000..10ba035d6
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ChangeManagementResponse.java
@@ -0,0 +1,19 @@
+package org.openecomp.vid.changeManagement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ChangeManagementResponse {
+ public List<CmResponse> cmResponses = null;
+
+
+
+ public ChangeManagementResponse(String vnfName) {
+ List<CmResponse> cmResponses = new ArrayList<>();
+ cmResponses.add(new CmResponse(vnfName));
+ this.cmResponses = cmResponses;
+
+ }
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CloudConfiguration.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CloudConfiguration.java
new file mode 100644
index 000000000..a5debc6db
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CloudConfiguration.java
@@ -0,0 +1,55 @@
+package org.openecomp.vid.changeManagement;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+"lcpCloudRegionId",
+"tenantId"
+})
+public class CloudConfiguration {
+ @JsonProperty("lcpCloudRegionId")
+ private String lcpCloudRegionId;
+ @JsonProperty("tenantId")
+ private String tenantId;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonProperty("lcpCloudRegionId")
+ public String getLcpCloudRegionId() {
+ return lcpCloudRegionId;
+ }
+
+ @JsonProperty("lcpCloudRegionId")
+ public void setLcpCloudRegionId(String lcpCloudRegionId) {
+ this.lcpCloudRegionId = lcpCloudRegionId;
+ }
+
+ @JsonProperty("tenantId")
+ public String getTenantId() {
+ return tenantId;
+ }
+
+ @JsonProperty("tenantId")
+ public void setTenantId(String tenantId) {
+ this.tenantId = tenantId;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CmResponse.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CmResponse.java
new file mode 100644
index 000000000..70e09d83c
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/CmResponse.java
@@ -0,0 +1,17 @@
+package org.openecomp.vid.changeManagement;
+
+public class CmResponse {
+
+ public String orchestratorRequestId;
+ public String serviceInstanceId;
+ public String vnfInstanceId;
+ public String vnfName;
+
+ public CmResponse(String vnfName){
+ this.orchestratorRequestId = "Request Id";
+ this.serviceInstanceId = "Service instance Id";
+ this.vnfInstanceId = "Vnf instance Id";
+ this.vnfName = vnfName;
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/LeanCloudConfiguration.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/LeanCloudConfiguration.java
new file mode 100644
index 000000000..663ff8c49
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/LeanCloudConfiguration.java
@@ -0,0 +1,20 @@
+package org.openecomp.vid.changeManagement;
+
+/**
+ * Created by Oren on 9/5/17.
+ */
+public class LeanCloudConfiguration {
+
+ public LeanCloudConfiguration() {
+ }
+
+ public LeanCloudConfiguration(org.openecomp.vid.domain.mso.CloudConfiguration cloudConfiguration) {
+ this.tenantId = cloudConfiguration.getTenantId();
+ this.lcpCloudRegionId = cloudConfiguration.getLcpCloudRegionId();
+
+ }
+ public String lcpCloudRegionId;
+
+ public String tenantId;
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfo.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfo.java
new file mode 100644
index 000000000..517628ca0
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfo.java
@@ -0,0 +1,138 @@
+package org.openecomp.vid.changeManagement;
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+"modelType",
+"modelInvariantId",
+"modelVersionId",
+"modelName",
+"modelVersion",
+"modelCustomizationName",
+"modelCustomizationId"
+})
+public class ModelInfo {
+
+ public ModelInfo(){
+
+ }
+
+ public ModelInfo(org.openecomp.vid.domain.mso.ModelInfo modelInfo){
+ this.setModelType(modelInfo.getModelType().toString());
+ this.setModelInvariantId(modelInfo.getModelInvariantId());
+ this.setModelVersionId(modelInfo.getModelNameVersionId());
+ this.setModelName(modelInfo.getModelName());
+ this.setModelVersion(modelInfo.getModelVersion());
+ this.setModelCustomizationId(modelInfo.getModelCustomizationId());
+ this.setModelVersionId(modelInfo.getModelVersionId());
+ }
+
+
+ @JsonProperty("modelType")
+ private String modelType;
+ @JsonProperty("modelInvariantId")
+ private String modelInvariantId;
+ @JsonProperty("modelVersionId")
+ private String modelVersionId;
+ @JsonProperty("modelName")
+ private String modelName;
+ @JsonProperty("modelVersion")
+ private String modelVersion;
+ @JsonProperty("modelCustomizationName")
+ private String modelCustomizationName;
+ @JsonProperty("modelCustomizationId")
+ private String modelCustomizationId;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonProperty("modelType")
+ public String getModelType() {
+ return modelType;
+ }
+
+ @JsonProperty("modelType")
+ public void setModelType(String modelType) {
+ this.modelType = modelType;
+ }
+
+ @JsonProperty("modelInvariantId")
+ public String getModelInvariantId() {
+ return modelInvariantId;
+ }
+
+ @JsonProperty("modelInvariantId")
+ public void setModelInvariantId(String modelInvariantId) {
+ this.modelInvariantId = modelInvariantId;
+ }
+
+ @JsonProperty("modelVersionId")
+ public String getModelVersionId() {
+ return modelVersionId;
+ }
+
+ @JsonProperty("modelVersionId")
+ public void setModelVersionId(String modelVersionId) {
+ this.modelVersionId = modelVersionId;
+ }
+
+ @JsonProperty("modelName")
+ public String getModelName() {
+ return modelName;
+ }
+
+ @JsonProperty("modelName")
+ public void setModelName(String modelName) {
+ this.modelName = modelName;
+ }
+
+ @JsonProperty("modelVersion")
+ public String getModelVersion() {
+ return modelVersion;
+ }
+
+ @JsonProperty("modelVersion")
+ public void setModelVersion(String modelVersion) {
+ this.modelVersion = modelVersion;
+ }
+
+ @JsonProperty("modelCustomizationName")
+ public String getModelCustomizationName() {
+ return modelCustomizationName;
+ }
+
+ @JsonProperty("modelCustomizationName")
+ public void setModelCustomizationName(String modelCustomizationName) {
+ this.modelCustomizationName = modelCustomizationName;
+ }
+
+ @JsonProperty("modelCustomizationId")
+ public String getModelCustomizationId() {
+ return modelCustomizationId;
+ }
+
+ @JsonProperty("modelCustomizationId")
+ public void setModelCustomizationId(String modelCustomizationId) {
+ this.modelCustomizationId = modelCustomizationId;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfoOfRelatedInstance.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfoOfRelatedInstance.java
new file mode 100644
index 000000000..c60ed2f77
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/ModelInfoOfRelatedInstance.java
@@ -0,0 +1,122 @@
+package org.openecomp.vid.changeManagement;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+"modelType",
+"modelInvariantId",
+"modelVersionId",
+"modelName",
+"modelVersion",
+"modelCustomizationName",
+"modelCustomizationId"
+})
+
+public class ModelInfoOfRelatedInstance {
+
+ @JsonProperty("modelType")
+ private String modelType;
+ @JsonProperty("modelInvariantId")
+ private String modelInvariantId;
+ @JsonProperty("modelVersionId")
+ private String modelVersionId;
+ @JsonProperty("modelName")
+ private String modelName;
+ @JsonProperty("modelVersion")
+ private String modelVersion;
+ @JsonProperty("modelCustomizationName")
+ private String modelCustomizationName;
+ @JsonProperty("modelCustomizationId")
+ private String modelCustomizationId;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonProperty("modelType")
+ public String getModelType() {
+ return modelType;
+ }
+
+ @JsonProperty("modelType")
+ public void setModelType(String modelType) {
+ this.modelType = modelType;
+ }
+
+ @JsonProperty("modelInvariantId")
+ public String getModelInvariantId() {
+ return modelInvariantId;
+ }
+
+ @JsonProperty("modelInvariantId")
+ public void setModelInvariantId(String modelInvariantId) {
+ this.modelInvariantId = modelInvariantId;
+ }
+
+ @JsonProperty("modelVersionId")
+ public String getModelVersionId() {
+ return modelVersionId;
+ }
+
+ @JsonProperty("modelVersionId")
+ public void setModelVersionId(String modelVersionId) {
+ this.modelVersionId = modelVersionId;
+ }
+
+ @JsonProperty("modelName")
+ public String getModelName() {
+ return modelName;
+ }
+
+ @JsonProperty("modelName")
+ public void setModelName(String modelName) {
+ this.modelName = modelName;
+ }
+
+ @JsonProperty("modelVersion")
+ public String getModelVersion() {
+ return modelVersion;
+ }
+
+ @JsonProperty("modelVersion")
+ public void setModelVersion(String modelVersion) {
+ this.modelVersion = modelVersion;
+ }
+
+ @JsonProperty("modelCustomizationName")
+ public String getModelCustomizationName() {
+ return modelCustomizationName;
+ }
+
+ @JsonProperty("modelCustomizationName")
+ public void setModelCustomizationName(String modelCustomizationName) {
+ this.modelCustomizationName = modelCustomizationName;
+ }
+
+ @JsonProperty("modelCustomizationId")
+ public String getModelCustomizationId() {
+ return modelCustomizationId;
+ }
+
+ @JsonProperty("modelCustomizationId")
+ public void setModelCustomizationId(String modelCustomizationId) {
+ this.modelCustomizationId = modelCustomizationId;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/MsoRequestDetails.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/MsoRequestDetails.java
new file mode 100644
index 000000000..9e442f28b
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/MsoRequestDetails.java
@@ -0,0 +1,31 @@
+package org.openecomp.vid.changeManagement;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Oren on 9/5/17.
+ */
+public class MsoRequestDetails {
+
+ public ModelInfo modelInfo;
+
+ public LeanCloudConfiguration cloudConfiguration;
+
+ public UpdateRequestInfo requestInfo;
+
+ public List<RelatedInstanceList> relatedInstanceList;
+
+ public RequestParameters requestParameters;
+
+ public MsoRequestDetails(RequestDetails r) {
+ this.modelInfo = new ModelInfo(r.getModelInfo());
+ this.cloudConfiguration = new LeanCloudConfiguration(r.getCloudConfiguration());
+ this.requestInfo = new UpdateRequestInfo(r.getRequestInfo());
+ this.relatedInstanceList = new ArrayList<>();
+ relatedInstanceList = r.getRelatedInstList();
+
+
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstance.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstance.java
new file mode 100644
index 000000000..49368c20e
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstance.java
@@ -0,0 +1,29 @@
+package org.openecomp.vid.changeManagement;
+
+import com.fasterxml.jackson.annotation.*;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "instanceId",
+ "modelInfo"
+})
+public class RelatedInstance {
+
+ @JsonProperty("instanceId")
+ public String instanceId;
+
+
+ @JsonProperty("modelInfo")
+ public ModelInfo modelInfo;
+
+ @JsonGetter
+ public String getInstanceId() {
+ return instanceId;
+ }
+
+ @JsonSetter
+ public void setInstanceId(String instanceId) {
+ this.instanceId = instanceId;
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstanceList.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstanceList.java
new file mode 100644
index 000000000..21a41c3f7
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RelatedInstanceList.java
@@ -0,0 +1,23 @@
+package org.openecomp.vid.changeManagement;
+
+import com.fasterxml.jackson.annotation.*;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "relatedInstance"
+})
+public class RelatedInstanceList {
+
+ @JsonProperty("relatedInstance")
+ public RelatedInstance relatedInstance;
+
+ @JsonSetter
+ public RelatedInstance getRelatedInstance() {
+ return relatedInstance;
+ }
+
+ @JsonSetter
+ public void setRelatedInstance(RelatedInstance relatedInstance) {
+ this.relatedInstance = relatedInstance;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetails.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetails.java
new file mode 100644
index 000000000..94e4c4468
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetails.java
@@ -0,0 +1,56 @@
+package org.openecomp.vid.changeManagement;
+
+import com.fasterxml.jackson.annotation.*;
+
+import java.util.List;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+"modelInfo",
+"cloudConfiguration",
+"requestInfo",
+"requestParameters",
+"vnfName",
+"vnfInstanceId"
+})
+public class RequestDetails extends org.openecomp.vid.mso.rest.RequestDetails{
+
+ @JsonProperty("vnfName")
+ private String vnfName;
+ @JsonProperty("vnfInstanceId")
+ private String vnfInstanceId;
+
+ /** The related model list. */
+ @JsonProperty("relatedInstanceList")
+ public List<RelatedInstanceList> relatedInstList;
+
+ @JsonProperty("vnfName")
+ public String getVnfName() {
+ return vnfName;
+ }
+
+ @JsonProperty("vnfName")
+ public void setVnfName(String vnfName) {
+ this.vnfName = vnfName;
+ }
+ @JsonProperty("vnfInstanceId")
+ public String getVnfInstanceId() {
+ return vnfInstanceId;
+ }
+
+ @JsonProperty("vnfInstanceId")
+ public void setVnfInstanceId(String vnfInstanceId) {
+ this.vnfInstanceId = vnfInstanceId;
+ }
+
+ @JsonGetter
+ public List<RelatedInstanceList> getRelatedInstList() {
+ return relatedInstList;
+ }
+
+ @JsonSetter
+ public void setRelatedInstList(List<RelatedInstanceList> relatedInstList) {
+ this.relatedInstList = relatedInstList;
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetailsWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetailsWrapper.java
new file mode 100644
index 000000000..2f49aff0a
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestDetailsWrapper.java
@@ -0,0 +1,9 @@
+package org.openecomp.vid.changeManagement;
+
+/**
+ * Created by Oren on 9/5/17.
+ */
+public class RequestDetailsWrapper {
+
+ public MsoRequestDetails requestDetails;
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestInfo.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestInfo.java
new file mode 100644
index 000000000..a7236c4b1
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestInfo.java
@@ -0,0 +1,69 @@
+package org.openecomp.vid.changeManagement;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+"source",
+"suppressRollback",
+"requestorId"
+})
+public class RequestInfo {
+ @JsonProperty("source")
+ private String source;
+ @JsonProperty("suppressRollback")
+ private Boolean suppressRollback;
+ @JsonProperty("requestorId")
+ private String requestorId;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonProperty("source")
+ public String getSource() {
+ return source;
+ }
+
+ @JsonProperty("source")
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ @JsonProperty("suppressRollback")
+ public Boolean getSuppressRollback() {
+ return suppressRollback;
+ }
+
+ @JsonProperty("suppressRollback")
+ public void setSuppressRollback(Boolean suppressRollback) {
+ this.suppressRollback = suppressRollback;
+ }
+
+ @JsonProperty("requestorId")
+ public String getRequestorId() {
+ return requestorId;
+ }
+
+ @JsonProperty("requestorId")
+ public void setRequestorId(String requestorId) {
+ this.requestorId = requestorId;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestParameters.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestParameters.java
new file mode 100644
index 000000000..37cad4735
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/RequestParameters.java
@@ -0,0 +1,44 @@
+package org.openecomp.vid.changeManagement;
+
+import java.util.HashMap;
+import java.util.Map;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+"usePreload"
+})
+
+public class RequestParameters {
+
+
+ @JsonProperty("usePreload")
+ private Boolean usePreload;
+ @JsonIgnore
+ private Map<String, Object> additionalProperties = new HashMap<String, Object>();
+
+ @JsonProperty("usePreload")
+ public Boolean getUsePreload() {
+ return usePreload;
+ }
+
+ @JsonProperty("usePreload")
+ public void setUsePreload(Boolean usePreload) {
+ this.usePreload = usePreload;
+ }
+
+ @JsonAnyGetter
+ public Map<String, Object> getAdditionalProperties() {
+ return this.additionalProperties;
+ }
+
+ @JsonAnySetter
+ public void setAdditionalProperty(String name, Object value) {
+ this.additionalProperties.put(name, value);
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/UpdateRequestInfo.java b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/UpdateRequestInfo.java
new file mode 100644
index 000000000..ab8189484
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/changeManagement/UpdateRequestInfo.java
@@ -0,0 +1,26 @@
+package org.openecomp.vid.changeManagement;
+
+import org.openecomp.vid.domain.mso.*;
+
+/**
+ * Created by Oren on 9/5/17.
+ */
+public class UpdateRequestInfo {
+
+ public UpdateRequestInfo() {
+ }
+
+
+ public UpdateRequestInfo(org.openecomp.vid.domain.mso.RequestInfo requestInfo) {
+ this.requestorId = requestInfo.getRequestorId();
+ this.suppressRollback = requestInfo.getSuppressRollback();
+ this.source = requestInfo.getSource();
+ }
+ public String source;
+
+ public Boolean suppressRollback;
+
+ public String requestorId;
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/AaiController.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/AaiController.java
index c0b6a5140..a8bdf39bb 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/controller/AaiController.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/AaiController.java
@@ -35,6 +35,7 @@ import org.openecomp.vid.aai.AaiResponse;
import org.openecomp.vid.aai.SubscriberData;
import org.openecomp.vid.aai.SubscriberFilteredResults;
import org.openecomp.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
+import org.openecomp.vid.model.VersionByInvariantIdsRequest;
import org.openecomp.vid.roles.Role;
import org.openecomp.vid.roles.RoleProvider;
import org.openecomp.vid.roles.RoleValidator;
@@ -43,13 +44,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
-
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@@ -70,859 +67,886 @@ import java.util.*;
@RestController
public class AaiController extends RestrictedBaseController {
-
- public AaiController() {
-
- }
-public AaiController(ServletContext servletContext) {
- this.servletContext = servletContext;
-
- }
-
-
-
-
- /**
- * The Constant dateFormat.
- */
- final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
- /**
- * The from app id.
- */
- protected String fromAppId = "VidAaiController";
- /**
- * The view name.
- */
- String viewName;
- /**
- * The logger.
- */
- EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiController.class);
-
-
- /**
- * The model.
- */
- private Map<String, Object> model = new HashMap<String, Object>();
- /**
- * The servlet context.
- */
- @Autowired
- private ServletContext servletContext;
-
- /**
- * aai service
- */
- @Autowired
- private AaiService aaiService;
-
-
-
- /**
- * Return tenant details.
- *
- * @param jsonObject the json object
- * @return String The parsing results
- */
- public static String parseCustomerObjectForTenants(JSONObject jsonObject) {
-
- JSONArray tenantArray = new JSONArray();
- boolean bconvert = false;
-
- try {
-
- JSONObject serviceSubsObj = (JSONObject) jsonObject.get("service-subscriptions");
-
- if (serviceSubsObj != null) {
- JSONArray srvcSubArray = (JSONArray) serviceSubsObj.get("service-subscription");
-
- if (srvcSubArray != null) {
- Iterator i = srvcSubArray.iterator();
-
- while (i.hasNext()) {
-
- JSONObject innerObj = (JSONObject) i.next();
-
- if (innerObj == null)
- continue;
-
- JSONObject relationShipListsObj = (JSONObject) innerObj.get("relationship-list");
- if (relationShipListsObj != null) {
- JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
- if (rShipArray != null) {
- Iterator i1 = rShipArray.iterator();
-
- while (i1.hasNext()) {
-
- JSONObject inner1Obj = (JSONObject) i1.next();
-
- if (inner1Obj == null)
- continue;
-
- String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
- if (relatedTo.equalsIgnoreCase("tenant")) {
- JSONObject tenantNewObj = new JSONObject();
-
- String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
- tenantNewObj.put("link", relatedLink);
-
- JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
- if (rDataArray != null) {
- Iterator i2 = rDataArray.iterator();
-
- while (i2.hasNext()) {
- JSONObject inner2Obj = (JSONObject) i2.next();
-
- if (inner2Obj == null)
- continue;
-
- String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
- String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
- if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
- tenantNewObj.put("cloudOwner", rShipVal);
- } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
- tenantNewObj.put("cloudRegionID", rShipVal);
- }
-
- if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
- tenantNewObj.put("tenantID", rShipVal);
- }
- }
- }
-
- JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
- if (relatedTPropArray != null) {
- Iterator i3 = relatedTPropArray.iterator();
-
- while (i3.hasNext()) {
- JSONObject inner3Obj = (JSONObject) i3.next();
-
- if (inner3Obj == null)
- continue;
-
- String propKey = checkForNull((String) inner3Obj.get("property-key"));
- String propVal = checkForNull((String) inner3Obj.get("property-value"));
- if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
- tenantNewObj.put("tenantName", propVal);
- }
- }
- }
- bconvert = true;
- tenantArray.add(tenantNewObj);
- }
- }
- }
- }
- }
- }
- }
- } catch (NullPointerException ex) {
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+ /**
+ * The from app id.
+ */
+ protected String fromAppId = "VidAaiController";
+ /**
+ * The view name.
+ */
+ String viewName;
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiController.class);
+ /**
+ * The model.
+ */
+ private Map<String, Object> model = new HashMap<String, Object>();
+ /**
+ * The servlet context.
+ */
+ @Autowired
+ private ServletContext servletContext;
+ /**
+ * aai service
+ */
+ @Autowired
+ private AaiService aaiService;
+ public AaiController() {
+
+ }
+
+ public AaiController(ServletContext servletContext) {
+ this.servletContext = servletContext;
+
+ }
+
+ /**
+ * Return tenant details.
+ *
+ * @param jsonObject the json object
+ * @return String The parsing results
+ */
+ public static String parseCustomerObjectForTenants(JSONObject jsonObject) {
+
+ JSONArray tenantArray = new JSONArray();
+ boolean bconvert = false;
+
+ try {
+
+ JSONObject serviceSubsObj = (JSONObject) jsonObject.get("service-subscriptions");
+
+ if (serviceSubsObj != null) {
+ JSONArray srvcSubArray = (JSONArray) serviceSubsObj.get("service-subscription");
+
+ if (srvcSubArray != null) {
+ Iterator i = srvcSubArray.iterator();
+
+ while (i.hasNext()) {
+
+ JSONObject innerObj = (JSONObject) i.next();
+
+ if (innerObj == null)
+ continue;
+
+ JSONObject relationShipListsObj = (JSONObject) innerObj.get("relationship-list");
+ if (relationShipListsObj != null) {
+ JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
+ if (rShipArray != null) {
+ Iterator i1 = rShipArray.iterator();
+
+ while (i1.hasNext()) {
+
+ JSONObject inner1Obj = (JSONObject) i1.next();
+
+ if (inner1Obj == null)
+ continue;
+
+ String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
+ if (relatedTo.equalsIgnoreCase("tenant")) {
+ JSONObject tenantNewObj = new JSONObject();
+
+ String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
+ tenantNewObj.put("link", relatedLink);
+
+ JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
+ if (rDataArray != null) {
+ Iterator i2 = rDataArray.iterator();
+
+ while (i2.hasNext()) {
+ JSONObject inner2Obj = (JSONObject) i2.next();
+
+ if (inner2Obj == null)
+ continue;
+
+ String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
+ String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
+ if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
+ tenantNewObj.put("cloudOwner", rShipVal);
+ } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
+ tenantNewObj.put("cloudRegionID", rShipVal);
+ }
+
+ if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
+ tenantNewObj.put("tenantID", rShipVal);
+ }
+ }
+ }
+
+ JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
+ if (relatedTPropArray != null) {
+ Iterator i3 = relatedTPropArray.iterator();
+
+ while (i3.hasNext()) {
+ JSONObject inner3Obj = (JSONObject) i3.next();
+
+ if (inner3Obj == null)
+ continue;
+
+ String propKey = checkForNull((String) inner3Obj.get("property-key"));
+ String propVal = checkForNull((String) inner3Obj.get("property-value"));
+ if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
+ tenantNewObj.put("tenantName", propVal);
+ }
+ }
+ }
+ bconvert = true;
+ tenantArray.add(tenantNewObj);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (NullPointerException ex) {
- }
- if (bconvert)
- return tenantArray.toJSONString();
- else
- return "";
+ }
- }
+ if (bconvert)
+ return tenantArray.toJSONString();
+ else
+ return "";
+ }
- /**
- * Retrieve the service subscription from the jsonObject.
- *
- * @param jsonObject the json object
- * @return String
- */
- public static String parseServiceSubscriptionObjectForTenants(JSONObject jsonObject) {
-
- JSONArray tenantArray = new JSONArray();
- boolean bconvert = false;
-
- try {
- JSONObject relationShipListsObj = (JSONObject) jsonObject.get("relationship-list");
- if (relationShipListsObj != null) {
- JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
- if (rShipArray != null) {
- Iterator i1 = rShipArray.iterator();
-
- while (i1.hasNext()) {
-
- JSONObject inner1Obj = (JSONObject) i1.next();
-
- if (inner1Obj == null)
- continue;
-
- String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
- if (relatedTo.equalsIgnoreCase("tenant")) {
- JSONObject tenantNewObj = new JSONObject();
-
- String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
- tenantNewObj.put("link", relatedLink);
-
- JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
- if (rDataArray != null) {
- Iterator i2 = rDataArray.iterator();
-
- while (i2.hasNext()) {
- JSONObject inner2Obj = (JSONObject) i2.next();
-
- if (inner2Obj == null)
- continue;
-
- String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
- String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
- if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
- tenantNewObj.put("cloudOwner", rShipVal);
- } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
- tenantNewObj.put("cloudRegionID", rShipVal);
- }
-
- if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
- tenantNewObj.put("tenantID", rShipVal);
- }
- }
- }
-
- JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
- if (relatedTPropArray != null) {
- Iterator i3 = relatedTPropArray.iterator();
-
- while (i3.hasNext()) {
- JSONObject inner3Obj = (JSONObject) i3.next();
-
- if (inner3Obj == null)
- continue;
-
- String propKey = checkForNull((String) inner3Obj.get("property-key"));
- String propVal = checkForNull((String) inner3Obj.get("property-value"));
- if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
- tenantNewObj.put("tenantName", propVal);
- }
- }
- }
- bconvert = true;
- tenantArray.add(tenantNewObj);
- }
- }
-
- }
- }
- } catch (NullPointerException ex) {
-
-
- }
-
- if (bconvert)
- return tenantArray.toJSONString();
- else
- return "";
-
- }
-
- /**
- * Check for null.
- *
- * @param local the local
- * @return the string
- */
- private static String checkForNull(String local) {
- if (local != null)
- return local;
- else
- return "";
-
- }
-
- /**
- * Welcome method.
- *
- * @param request the request
- * @return ModelAndView The view
- */
- @RequestMapping(value = {"/subscriberSearch"}, method = RequestMethod.GET)
- public ModelAndView welcome(HttpServletRequest request) {
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== AaiController welcome start");
- return new ModelAndView(getViewName());
- }
-
- @RequestMapping(value = {"/aai_get_aic_zones"}, method = RequestMethod.GET)
- public ResponseEntity<String> getAicZones(HttpServletRequest request) throws JsonGenerationException, JsonMappingException, IOException {
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== getAicZones controller start");
- AaiResponse response = aaiService.getAaiZones();
- return aaiResponseToResponseEntity(response);
-
- }
-
- /* (non-Javadoc)
- * @see org.openecomp.portalsdk.core.controller.RestrictedBaseController#getViewName()
- */
- public String getViewName() {
- return viewName;
- }
-
- /* (non-Javadoc)
- * @see org.openecomp.portalsdk.core.controller.RestrictedBaseController#setViewName(java.lang.String)
- */
- public void setViewName(String viewName) {
- this.viewName = viewName;
- }
-
- /**
- * Get services from a&ai.
- *
- * @return ResponseEntity<String> The response entity with the logged in user uuid.
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = {"/getuserID"}, method = RequestMethod.GET)
- public ResponseEntity<String> getUserID(HttpServletRequest request) throws IOException, InterruptedException {
-
- String userId = "";
- HttpSession session = request.getSession();
- if (session != null) {
- User user = (User) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME));
- if (user != null) {
- //userId = user.getHrid();
- userId = user.getLoginId();
- if (userId == null)
- userId = user.getOrgUserId();
- }
- }
-
- return new ResponseEntity<String>(userId, HttpStatus.OK);
- }
-
- /**
- * Get services from a&ai.
- *
- * @return ResponseEntity<String> The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = "/aai_get_services", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> doGetServices(HttpServletRequest request) throws IOException, InterruptedException {
-
- RoleValidator roleValidator = new RoleValidator(new RoleProvider().getUserRoles(request));
-
- AaiResponse subscriberList = aaiService.getServices(roleValidator);
- ResponseEntity<String> responseEntity = aaiResponseToResponseEntity( subscriberList);
-
- return responseEntity;
- }
-
-
-
- private ResponseEntity<String> aaiResponseToResponseEntity( AaiResponse aaiResponseData)
- throws IOException, JsonGenerationException, JsonMappingException {
- ResponseEntity<String> responseEntity;
- ObjectMapper objectMapper = new ObjectMapper();
- if (aaiResponseData.getHttpCode() == 200) {
- responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(aaiResponseData.getT()), HttpStatus.OK);
- } else {
- responseEntity = new ResponseEntity<String>(aaiResponseData.getErrorMessage(), HttpStatus.valueOf(aaiResponseData.getHttpCode()));
- }
- return responseEntity;
- }
-
- /**
- * Lookup single service instance in a&ai. Get the service-subscription and customer, too, i guess?
- *
- * @param serviceInstanceId the service instance Id
- * @return ResponseEntity The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = "/aai_get_service_instance/{service-instance-id}/{service-instance-type}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> doGetServiceInstance(@PathVariable("service-instance-id") String serviceInstanceId, @PathVariable("service-instance-type") String serviceInstanceType) throws IOException, InterruptedException {
- File certiPath = GetCertificatesPath();
- Response resp = null;
-
- if (serviceInstanceType.equalsIgnoreCase("Service Instance Id")) {
- resp = doAaiGet(certiPath.getAbsolutePath(),
- "search/nodes-query?search-node-type=service-instance&filter=service-instance-id:EQUALS:"
- + serviceInstanceId, false);
- } else {
- resp = doAaiGet(certiPath.getAbsolutePath(),
- "search/nodes-query?search-node-type=service-instance&filter=service-instance-name:EQUALS:"
- + serviceInstanceId, false);
- }
- return convertResponseToResponseEntity(resp);
- }
-
- /**
- * Get services from a&ai.
- *
- * @param globalCustomerId the global customer id
- * @param serviceSubscriptionId the service subscription id
- * @return ResponseEntity The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = "/aai_get_service_subscription/{global-customer-id}/{service-subscription-id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> doGetServices(@PathVariable("global-customer-id") String globalCustomerId,
- @PathVariable("service-subscription-id") String serviceSubscriptionId) throws IOException, InterruptedException {
- File certiPath = GetCertificatesPath();
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + globalCustomerId
- + "/service-subscriptions/service-subscription/" + serviceSubscriptionId + "?depth=0", false);
- return convertResponseToResponseEntity(resp);
- }
-
- /**
- * Obtain the subscriber list from a&ai.
- *
- * @param fullSet the full set
- * @return ResponseEntity The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = "/aai_get_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> doGetSubscriberList(HttpServletRequest request,@DefaultValue("n") @QueryParam("fullSet") String fullSet) throws IOException, InterruptedException {
- return getFullSubscriberList(request);
- }
-
- /**
- * Obtain the Target Prov Status from the System.Properties file.
- *
- * @return ResponseEntity The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = "/get_system_prop_vnf_prov_status", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> getTargetProvStatus() throws IOException, InterruptedException {
- String p = SystemProperties.getProperty("aai.vnf.provstatus");
- return new ResponseEntity<String>(p, HttpStatus.OK);
- }
-
- /**
- * Obtain the full subscriber list from a&ai.
- * <p>
- * g @return ResponseEntity The response entity
- *
- * @throws IOException Signals that an I/O exception has occurred.
- * @throws InterruptedException the interrupted exception
- */
- @RequestMapping(value = "/aai_get_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> getFullSubscriberList(HttpServletRequest request) throws IOException, InterruptedException {
- ObjectMapper objectMapper = new ObjectMapper();
- ResponseEntity<String> responseEntity;
- RoleValidator roleValidator = new RoleValidator(new RoleProvider().getUserRoles(request));
- SubscriberFilteredResults subscriberList = aaiService.getFullSubscriberList(roleValidator);
- if (subscriberList.getHttpCode() == 200) {
- responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(subscriberList.getSubscriberList()), HttpStatus.OK);
- } else {
- responseEntity = new ResponseEntity<String>(subscriberList.getErrorMessage(), HttpStatus.valueOf(subscriberList.getHttpCode()));
- }
-
-
- return responseEntity;
- }
-
- /**
- * Refresh the subscriber list from a&ai.
- *
- * @return ResponseEntity The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- */
- @RequestMapping(value = "/aai_refresh_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> doRefreshSubscriberList() throws IOException {
- Response resp = getSubscribers(false);
- return convertResponseToResponseEntity(resp);
- }
-
- /**
- * Refresh the full subscriber list from a&ai.
- *
- * @return ResponseEntity The response entity
- * @throws IOException Signals that an I/O exception has occurred.
- */
- @RequestMapping(value = "/aai_refresh_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
- public ResponseEntity<String> doRefreshFullSubscriberList() throws IOException {
- Response resp = getSubscribers(false);
- return convertResponseToResponseEntity(resp);
- }
-
- /**
- * Get subscriber details from a&ai.
- *
- * @param subscriberId the subscriber id
- * @return ResponseEntity The response entity
- */
- @RequestMapping(value = "/aai_sub_details/{subscriberId}", method = RequestMethod.GET)
- public ResponseEntity<String> GetSubscriberDetails(HttpServletRequest request,@PathVariable("subscriberId") String subscriberId) throws IOException {
- ObjectMapper objectMapper = new ObjectMapper();
- ResponseEntity responseEntity;
- List<Role> roles = new RoleProvider().getUserRoles(request);
- RoleValidator roleValidator = new RoleValidator(roles);
- AaiResponse<SubscriberData> subscriberData = aaiService.getSubscriberData(subscriberId,roleValidator);
- String httpMessage = subscriberData.getT() != null ?
- objectMapper.writeValueAsString(subscriberData.getT()) :
- subscriberData.getErrorMessage();
-
- responseEntity = new ResponseEntity<String>(httpMessage, HttpStatus.valueOf(subscriberData.getHttpCode()));
- return responseEntity;
- }
-
- /**
- * Issue a named query to a&ai.
- *
- * @param namedQueryId the named query id
- * @param globalCustomerId the global customer id
- * @param serviceType the service type
- * @param serviceInstance the service instance
- * @return ResponseEntity The response entity
- */
- @RequestMapping(value = "/aai_sub_viewedit/{namedQueryId}/{globalCustomerId}/{serviceType}/{serviceInstance}", method = RequestMethod.GET)
- public ResponseEntity<String> viewEditGetComponentList(
- @PathVariable("namedQueryId") String namedQueryId,
- @PathVariable("globalCustomerId") String globalCustomerId,
- @PathVariable("serviceType") String serviceType,
- @PathVariable("serviceInstance") String serviceInstance) {
-
- String componentListPayload = getComponentListPutPayload(namedQueryId, globalCustomerId, serviceType, serviceInstance);
- File certiPath = GetCertificatesPath();
-
- Response resp = doAaiPost(certiPath.getAbsolutePath(), "search/named-query", componentListPayload, false);
- return convertResponseToResponseEntity(resp);
- }
-
-
- // @RequestMapping(value="/aai_get_tenants/{global-customer-id}", method = RequestMethod.GET)
- // public ResponseEntity<String> viewEditGetComponentList(
- // @PathVariable("global-customer-id") String globalCustomerId) {
- // return new ResponseEntity<String>(getTenants(globalCustomerId), HttpStatus.OK);
- // }
-
- /**
- * Issue a named query to a&ai.
- *
- * @param namedQueryId the named query id
- * @param globalCustomerId the global customer id
- * @param serviceType the service type
- * @return ResponseEntity The response entity
- */
- @RequestMapping(value = "/aai_get_models_by_service_type/{namedQueryId}/{globalCustomerId}/{serviceType}", method = RequestMethod.GET)
- public ResponseEntity<String> viewEditGetComponentList(
- @PathVariable("namedQueryId") String namedQueryId,
- @PathVariable("globalCustomerId") String globalCustomerId,
- @PathVariable("serviceType") String serviceType) {
-
- String componentListPayload = getModelsByServiceTypePayload(namedQueryId, globalCustomerId, serviceType);
- File certiPath = GetCertificatesPath();
-
- Response resp = doAaiPost(certiPath.getAbsolutePath(), "search/named-query", componentListPayload, false);
- return convertResponseToResponseEntity(resp);
- }
-
- /**
- * Parses the for tenants.
- *
- * @param resp the resp
- * @return the string
- */
- private String parseForTenants(String resp) {
- String tenantList = "";
-
- try {
- JSONParser jsonParser = new JSONParser();
-
- JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
-
- return parseCustomerObjectForTenants(jsonObject);
- } catch (Exception ex) {
-
- }
-
- return tenantList;
- }
-
- /**
- * Parses the for tenants by service subscription.
- *
- * @param resp the resp
- * @return the string
- */
- private String parseForTenantsByServiceSubscription(String resp) {
- String tenantList = "";
-
- try {
- JSONParser jsonParser = new JSONParser();
-
- JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
-
- return parseServiceSubscriptionObjectForTenants(jsonObject);
- } catch (Exception ex) {
-
- }
-
- return tenantList;
- }
-
- /**
- * Obtain tenants for a given service type.
- *
- * @param globalCustomerId the global customer id
- * @param serviceType the service type
- * @return ResponseEntity The response entity
- */
- @RequestMapping(value = "/aai_get_tenants/{global-customer-id}/{service-type}", method = RequestMethod.GET)
- public ResponseEntity<String> viewEditGetTenantsFromServiceType(HttpServletRequest request,
- @PathVariable("global-customer-id") String globalCustomerId, @PathVariable("service-type") String serviceType) {
-
- ResponseEntity responseEntity;
- try {
- ObjectMapper objectMapper = new ObjectMapper();
- List<Role> roles = new RoleProvider().getUserRoles(request);
- RoleValidator roleValidator = new RoleValidator(roles);
- AaiResponse<GetTenantsResponse[]> response = aaiService.getTenants(globalCustomerId, serviceType, roleValidator);
- if (response.getHttpCode() == 200) {
- responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(response.getT()), HttpStatus.OK);
- } else {
- responseEntity = new ResponseEntity<String>(response.getErrorMessage(), HttpStatus.valueOf(response.getHttpCode()));
- }
- }
- catch (Exception e){
- responseEntity = new ResponseEntity<String>("Unable to proccess getTenants reponse", HttpStatus.INTERNAL_SERVER_ERROR);
- }
- return responseEntity;
- }
-
-
- private ResponseEntity<String> convertResponseToResponseEntity(Response resp) {
- ResponseEntity<String> respEnt;
- ObjectMapper objectMapper = new ObjectMapper();
- if (resp == null) {
- respEnt = new ResponseEntity<String>("Failed to fetch data from A&AI, check server logs for details.", HttpStatus.INTERNAL_SERVER_ERROR);
- } else {
- respEnt = new ResponseEntity<String>(resp.readEntity(String.class), HttpStatus.valueOf(resp.getStatus()));
- }
- return respEnt;
- }
-
- /**
- * Gets the tenants.
- *
- * @param globalCustomerId the global customer id
- * @return the tenants
- */
- private ResponseEntity<String> getTenants(String globalCustomerId) {
- File certiPath = GetCertificatesPath();
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + globalCustomerId, false);
-
- ResponseEntity<String> respEnt;
- if (resp.getStatus() >= 200 && resp.getStatus() <= 299) {
- respEnt = new ResponseEntity<String>(parseForTenants((String) resp.readEntity(String.class)), HttpStatus.OK);
- } else {
- respEnt = new ResponseEntity<String>((String) resp.readEntity(String.class), HttpStatus.valueOf(resp.getStatus()));
- }
- return respEnt;
-
- }
-
- /**
- * Gets the tenants from service type.
- *
- * @param globalCustomerId the global customer id
- * @param serviceType the service type
- * @return the tenants from service type
- */
- private ResponseEntity<String> getTenantsFromServiceType(String globalCustomerId, String serviceType) {
-
-
-
-
-
- File certiPath = GetCertificatesPath();
- String url = "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + serviceType;
-
- Response resp = doAaiGet(certiPath.getAbsolutePath(), url, false);
-
- ResponseEntity<String> respEnt;
- if (resp.getStatus() >= 200 && resp.getStatus() <= 299) {
- respEnt = new ResponseEntity<String>(parseForTenantsByServiceSubscription((String) resp.readEntity(String.class)), HttpStatus.OK);
- } else {
- respEnt = new ResponseEntity<String>((String) resp.readEntity(String.class), HttpStatus.valueOf(resp.getStatus()));
- }
- return respEnt;
-
- }
-
- /**
- * Gets the services.
- *
- * @return the services
- */
- private Response getServices() {
- File certiPath = GetCertificatesPath();
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "service-design-and-creation/services", false);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getServices() resp=" + resp.getStatusInfo());
-
- //model.put("aai_get_services", resp);
- return resp;
- }
-
- /**
- * Gets the subscribers.
- *
- * @param isFullSet the is full set
- * @return the subscribers
- */
- private Response getSubscribers(boolean isFullSet) {
-
- File certiPath = GetCertificatesPath();
- String depth = "0";
-
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers?subscriber-type=INFRA&depth=" + depth, false);
- if (resp != null) {
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscribers() resp=" + resp.getStatusInfo().toString());
- }
- return resp;
- }
-
- /**
- * Gets the subscriber details.
- *
- * @param subscriberId the subscriber id
- * @return the subscriber details
- */
- private Response getSubscriberDetails(String subscriberId) {
- File certiPath = GetCertificatesPath();
- Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + subscriberId + "?depth=2", false);
- //String resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + subscriberId, false);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscriberDetails() resp=" + resp.getStatusInfo().toString());
- return resp;
- }
-
- /**
- * Gets the certificates path.
- *
- * @return the file
- */
- private File GetCertificatesPath() {
- if (servletContext != null)
- return new File(servletContext.getRealPath("/WEB-INF/cert/"));
- return null;
- }
-
- /**
- * Send a GET request to a&ai.
- *
- * @param certiPath the certi path
- * @param uri the uri
- * @param xml the xml
- * @return String The response
- */
- protected Response doAaiGet(String certiPath, String uri, boolean xml) {
- String methodName = "getSubscriberList";
- String transId = UUID.randomUUID().toString();
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
-
- Response resp = null;
- try {
-
- AAIRestInterface restContrller = new AAIRestInterface(certiPath);
- resp = restContrller.RestGet(fromAppId, transId, uri, xml);
-
- } catch (WebApplicationException e) {
- final String message = ((BadRequestException) e).getResponse().readEntity(String.class);
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- }
-
- return resp;
- }
-
- /**
- * Send a POST request to a&ai.
- *
- * @param certiPath the certi path
- * @param uri the uri
- * @param payload the payload
- * @param xml the xml
- * @return String The response
- */
- protected Response doAaiPost(String certiPath, String uri, String payload, boolean xml) {
- String methodName = "getSubscriberList";
- String transId = UUID.randomUUID().toString();
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
-
- Response resp = null;
- try {
-
- AAIRestInterface restContrller = new AAIRestInterface(certiPath);
- resp = restContrller.RestPost(fromAppId, transId, uri, payload, xml);
-
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- }
-
- return resp;
- }
-
- /**
- * Gets the component list put payload.
- *
- * @param namedQueryId the named query id
- * @param globalCustomerId the global customer id
- * @param serviceType the service type
- * @param serviceInstance the service instance
- * @return the component list put payload
- */
- private String getComponentListPutPayload(String namedQueryId, String globalCustomerId, String serviceType, String serviceInstance) {
- return
- " {" +
- " \"instance-filters\": {" +
- " \"instance-filter\": [" +
- " {" +
- " \"customer\": {" +
- " \"global-customer-id\": \"" + globalCustomerId + "\"" +
- " }," +
- " \"service-instance\": {" +
- " \"service-instance-id\": \"" + serviceInstance + "\"" +
- " }," +
- " \"service-subscription\": {" +
- " \"service-type\": \"" + serviceType + "\"" +
- " }" +
- " }" +
- " ]" +
- " }," +
- " \"query-parameters\": {" +
- " \"named-query\": {" +
- " \"named-query-uuid\": \"" + namedQueryId + "\"" +
- " }" +
- " }" +
- "}";
-
- }
-
- private String getModelsByServiceTypePayload(String namedQueryId, String globalCustomerId, String serviceType) {
- // TODO Auto-generated method stub
- return " {" +
- " \"instance-filters\": {" +
- " \"instance-filter\": [" +
- " {" +
- " \"customer\": {" +
- " \"global-customer-id\": \"" + globalCustomerId + "\"" +
- " }," +
- " \"service-subscription\": {" +
- " \"service-type\": \"" + serviceType + "\"" +
- " }" +
- " }" +
- " ]" +
- " }," +
- " \"query-parameters\": {" +
- " \"named-query\": {" +
- " \"named-query-uuid\": \"" + namedQueryId + "\"" +
- " }" +
- " }" +
- "}";
-
- }
+ /**
+ * Retrieve the service subscription from the jsonObject.
+ *
+ * @param jsonObject the json object
+ * @return String
+ */
+ public static String parseServiceSubscriptionObjectForTenants(JSONObject jsonObject) {
+
+ JSONArray tenantArray = new JSONArray();
+ boolean bconvert = false;
+
+ try {
+ JSONObject relationShipListsObj = (JSONObject) jsonObject.get("relationship-list");
+ if (relationShipListsObj != null) {
+ JSONArray rShipArray = (JSONArray) relationShipListsObj.get("relationship");
+ if (rShipArray != null) {
+ Iterator i1 = rShipArray.iterator();
+
+ while (i1.hasNext()) {
+
+ JSONObject inner1Obj = (JSONObject) i1.next();
+
+ if (inner1Obj == null)
+ continue;
+
+ String relatedTo = checkForNull((String) inner1Obj.get("related-to"));
+ if (relatedTo.equalsIgnoreCase("tenant")) {
+ JSONObject tenantNewObj = new JSONObject();
+
+ String relatedLink = checkForNull((String) inner1Obj.get("related-link"));
+ tenantNewObj.put("link", relatedLink);
+
+ JSONArray rDataArray = (JSONArray) inner1Obj.get("relationship-data");
+ if (rDataArray != null) {
+ Iterator i2 = rDataArray.iterator();
+
+ while (i2.hasNext()) {
+ JSONObject inner2Obj = (JSONObject) i2.next();
+
+ if (inner2Obj == null)
+ continue;
+
+ String rShipKey = checkForNull((String) inner2Obj.get("relationship-key"));
+ String rShipVal = checkForNull((String) inner2Obj.get("relationship-value"));
+ if (rShipKey.equalsIgnoreCase("cloud-region.cloud-owner")) {
+ tenantNewObj.put("cloudOwner", rShipVal);
+ } else if (rShipKey.equalsIgnoreCase("cloud-region.cloud-region-id")) {
+ tenantNewObj.put("cloudRegionID", rShipVal);
+ }
+
+ if (rShipKey.equalsIgnoreCase("tenant.tenant-id")) {
+ tenantNewObj.put("tenantID", rShipVal);
+ }
+ }
+ }
+
+ JSONArray relatedTPropArray = (JSONArray) inner1Obj.get("related-to-property");
+ if (relatedTPropArray != null) {
+ Iterator i3 = relatedTPropArray.iterator();
+
+ while (i3.hasNext()) {
+ JSONObject inner3Obj = (JSONObject) i3.next();
+
+ if (inner3Obj == null)
+ continue;
+
+ String propKey = checkForNull((String) inner3Obj.get("property-key"));
+ String propVal = checkForNull((String) inner3Obj.get("property-value"));
+ if (propKey.equalsIgnoreCase("tenant.tenant-name")) {
+ tenantNewObj.put("tenantName", propVal);
+ }
+ }
+ }
+ bconvert = true;
+ tenantArray.add(tenantNewObj);
+ }
+ }
+
+ }
+ }
+ } catch (NullPointerException ex) {
+
+
+ }
+
+ if (bconvert)
+ return tenantArray.toJSONString();
+ else
+ return "";
+
+ }
+
+ /**
+ * Check for null.
+ *
+ * @param local the local
+ * @return the string
+ */
+ private static String checkForNull(String local) {
+ if (local != null)
+ return local;
+ else
+ return "";
+
+ }
+
+ /**
+ * Welcome method.
+ *
+ * @param request the request
+ * @return ModelAndView The view
+ */
+ @RequestMapping(value = {"/subscriberSearch"}, method = RequestMethod.GET)
+ public ModelAndView welcome(HttpServletRequest request) {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== AaiController welcome start");
+ return new ModelAndView(getViewName());
+ }
+
+ @RequestMapping(value = {"/aai_get_aic_zones"}, method = RequestMethod.GET)
+ public ResponseEntity<String> getAicZones(HttpServletRequest request) throws JsonGenerationException, JsonMappingException, IOException {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== getAicZones controller start");
+ AaiResponse response = aaiService.getAaiZones();
+ return aaiResponseToResponseEntity(response);
+ }
+
+ @RequestMapping(value = {"/aai_get_aic_zone_for_pnf/{globalCustomerId}/{serviceType}/{serviceId}"}, method = RequestMethod.GET)
+ public ResponseEntity<String> getAicZoneForPnf(@PathVariable("globalCustomerId") String globalCustomerId ,@PathVariable("serviceType") String serviceType , @PathVariable("serviceId") String serviceId ,HttpServletRequest request) throws JsonGenerationException, JsonMappingException, IOException {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== getAicZoneForPnf controller start");
+ AaiResponse response = aaiService.getAicZoneForPnf(globalCustomerId , serviceType , serviceId);
+ return aaiResponseToResponseEntity(response);
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.portalsdk.core.controller.RestrictedBaseController#getViewName()
+ */
+ public String getViewName() {
+ return viewName;
+ }
+
+ /* (non-Javadoc)
+ * @see org.openecomp.portalsdk.core.controller.RestrictedBaseController#setViewName(java.lang.String)
+ */
+ public void setViewName(String viewName) {
+ this.viewName = viewName;
+ }
+
+ /**
+ * Get services from a&ai.
+ *
+ * @return ResponseEntity<String> The response entity with the logged in user uuid.
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = {"/getuserID"}, method = RequestMethod.GET)
+ public ResponseEntity<String> getUserID(HttpServletRequest request) throws IOException, InterruptedException {
+
+ String userId = "";
+ HttpSession session = request.getSession();
+ if (session != null) {
+ User user = (User) session.getAttribute(SystemProperties.getProperty(SystemProperties.USER_ATTRIBUTE_NAME));
+ if (user != null) {
+ //userId = user.getHrid();
+ userId = user.getLoginId();
+ if (userId == null)
+ userId = user.getOrgUserId();
+ }
+ }
+
+ return new ResponseEntity<String>(userId, HttpStatus.OK);
+ }
+
+ /**
+ * Get services from a&ai.
+ *
+ * @return ResponseEntity<String> The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = "/aai_get_services", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> doGetServices(HttpServletRequest request) throws IOException, InterruptedException {
+
+ RoleValidator roleValidator = new RoleValidator(new RoleProvider().getUserRoles(request));
+
+ AaiResponse subscriberList = aaiService.getServices(roleValidator);
+ ResponseEntity<String> responseEntity = aaiResponseToResponseEntity(subscriberList);
+
+ return responseEntity;
+ }
+
+
+ @RequestMapping(value = {"/aai_get_version_by_invariant_id"}, method = RequestMethod.POST)
+ public ResponseEntity<String> getVersionByInvariantId(HttpServletRequest request, @RequestBody VersionByInvariantIdsRequest versions) throws IOException {
+ ResponseEntity<String> responseEntity;
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ Response result = aaiService.getVersionByInvariantId(versions.versions);
+
+ return new ResponseEntity<String>(result.readEntity(String.class), HttpStatus.OK);
+ }
+
+
+ private ResponseEntity<String> aaiResponseToResponseEntity(AaiResponse aaiResponseData)
+ throws IOException, JsonGenerationException, JsonMappingException {
+ ResponseEntity<String> responseEntity;
+ ObjectMapper objectMapper = new ObjectMapper();
+ if (aaiResponseData.getHttpCode() == 200) {
+ responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(aaiResponseData.getT()), HttpStatus.OK);
+ } else {
+ responseEntity = new ResponseEntity<String>(aaiResponseData.getErrorMessage(), HttpStatus.valueOf(aaiResponseData.getHttpCode()));
+ }
+ return responseEntity;
+ }
+
+ /**
+ * Lookup single service instance in a&ai. Get the service-subscription and customer, too, i guess?
+ *
+ * @param serviceInstanceId the service instance Id
+ * @return ResponseEntity The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = "/aai_get_service_instance/{service-instance-id}/{service-instance-type}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> doGetServiceInstance(@PathVariable("service-instance-id") String serviceInstanceId, @PathVariable("service-instance-type") String serviceInstanceType) throws IOException, InterruptedException {
+ File certiPath = GetCertificatesPath();
+ Response resp = null;
+
+ if (serviceInstanceType.equalsIgnoreCase("Service Instance Id")) {
+ resp = doAaiGet(certiPath.getAbsolutePath(),
+ "search/nodes-query?search-node-type=service-instance&filter=service-instance-id:EQUALS:"
+ + serviceInstanceId, false);
+ } else {
+ resp = doAaiGet(certiPath.getAbsolutePath(),
+ "search/nodes-query?search-node-type=service-instance&filter=service-instance-name:EQUALS:"
+ + serviceInstanceId, false);
+ }
+ return convertResponseToResponseEntity(resp);
+ }
+
+ /**
+ * Get services from a&ai.
+ *
+ * @param globalCustomerId the global customer id
+ * @param serviceSubscriptionId the service subscription id
+ * @return ResponseEntity The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = "/aai_get_service_subscription/{global-customer-id}/{service-subscription-id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> doGetServices(@PathVariable("global-customer-id") String globalCustomerId,
+ @PathVariable("service-subscription-id") String serviceSubscriptionId) throws IOException, InterruptedException {
+ File certiPath = GetCertificatesPath();
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + globalCustomerId
+ + "/service-subscriptions/service-subscription/" + serviceSubscriptionId + "?depth=0", false);
+ return convertResponseToResponseEntity(resp);
+ }
+
+ /**
+ * Obtain the subscriber list from a&ai.
+ *
+ * @param fullSet the full set
+ * @return ResponseEntity The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = "/aai_get_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> doGetSubscriberList(HttpServletRequest request, @DefaultValue("n") @QueryParam("fullSet") String fullSet) throws IOException, InterruptedException {
+ return getFullSubscriberList(request);
+ }
+
+ /**
+ * Obtain the Target Prov Status from the System.Properties file.
+ *
+ * @return ResponseEntity The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = "/get_system_prop_vnf_prov_status", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> getTargetProvStatus() throws IOException, InterruptedException {
+ String p = SystemProperties.getProperty("aai.vnf.provstatus");
+ return new ResponseEntity<String>(p, HttpStatus.OK);
+ }
+
+ /**
+ * Obtain the full subscriber list from a&ai.
+ * <p>
+ * g @return ResponseEntity The response entity
+ *
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws InterruptedException the interrupted exception
+ */
+ @RequestMapping(value = "/aai_get_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> getFullSubscriberList(HttpServletRequest request) throws IOException, InterruptedException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ ResponseEntity<String> responseEntity;
+ RoleValidator roleValidator = new RoleValidator(new RoleProvider().getUserRoles(request));
+ SubscriberFilteredResults subscriberList = aaiService.getFullSubscriberList(roleValidator);
+ if (subscriberList.getHttpCode() == 200) {
+ responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(subscriberList.getSubscriberList()), HttpStatus.OK);
+ } else {
+ responseEntity = new ResponseEntity<String>(subscriberList.getErrorMessage(), HttpStatus.valueOf(subscriberList.getHttpCode()));
+ }
+
+
+ return responseEntity;
+ }
+
+
+ @RequestMapping(value = "/get_vnf_data_by_globalid_and_service_type/{globalCustomerId}/{serviceType}",
+ method = RequestMethod.GET,
+ produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> getVnfDataByGlobalIdAndServiceType(HttpServletRequest request,
+ @PathVariable("globalCustomerId") String globalCustomerId,
+ @PathVariable("serviceType") String serviceType) throws IOException {
+
+ Response resp = aaiService.getVNFData(globalCustomerId, serviceType);
+ return convertResponseToResponseEntity(resp);
+ }
+
+
+ /**
+ * Refresh the subscriber list from a&ai.
+ *
+ * @return ResponseEntity The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ @RequestMapping(value = "/aai_refresh_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> doRefreshSubscriberList() throws IOException {
+ Response resp = getSubscribers(false);
+ return convertResponseToResponseEntity(resp);
+ }
+
+ /**
+ * Refresh the full subscriber list from a&ai.
+ *
+ * @return ResponseEntity The response entity
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ @RequestMapping(value = "/aai_refresh_full_subscribers", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
+ public ResponseEntity<String> doRefreshFullSubscriberList() throws IOException {
+ Response resp = getSubscribers(false);
+ return convertResponseToResponseEntity(resp);
+ }
+
+ /**
+ * Get subscriber details from a&ai.
+ *
+ * @param subscriberId the subscriber id
+ * @return ResponseEntity The response entity
+ */
+ @RequestMapping(value = "/aai_sub_details/{subscriberId}", method = RequestMethod.GET)
+ public ResponseEntity<String> GetSubscriberDetails(HttpServletRequest request, @PathVariable("subscriberId") String subscriberId) throws IOException {
+ ObjectMapper objectMapper = new ObjectMapper();
+ ResponseEntity responseEntity;
+ List<Role> roles = new RoleProvider().getUserRoles(request);
+ RoleValidator roleValidator = new RoleValidator(roles);
+ AaiResponse<SubscriberData> subscriberData = aaiService.getSubscriberData(subscriberId, roleValidator);
+ String httpMessage = subscriberData.getT() != null ?
+ objectMapper.writeValueAsString(subscriberData.getT()) :
+ subscriberData.getErrorMessage();
+
+ responseEntity = new ResponseEntity<String>(httpMessage, HttpStatus.valueOf(subscriberData.getHttpCode()));
+ return responseEntity;
+ }
+
+ /**
+ * Issue a named query to a&ai.
+ *
+ * @param namedQueryId the named query id
+ * @param globalCustomerId the global customer id
+ * @param serviceType the service type
+ * @param serviceInstance the service instance
+ * @return ResponseEntity The response entity
+ */
+ @RequestMapping(value = "/aai_sub_viewedit/{namedQueryId}/{globalCustomerId}/{serviceType}/{serviceInstance}", method = RequestMethod.GET)
+ public ResponseEntity<String> viewEditGetComponentList(
+ @PathVariable("namedQueryId") String namedQueryId,
+ @PathVariable("globalCustomerId") String globalCustomerId,
+ @PathVariable("serviceType") String serviceType,
+ @PathVariable("serviceInstance") String serviceInstance) {
+
+ String componentListPayload = getComponentListPutPayload(namedQueryId, globalCustomerId, serviceType, serviceInstance);
+ File certiPath = GetCertificatesPath();
+
+ Response resp = doAaiPost(certiPath.getAbsolutePath(), "search/named-query", componentListPayload, false);
+ return convertResponseToResponseEntity(resp);
+ }
+
+
+ @RequestMapping(value = "/aai_get_vnf_data/{globalCustomerId}/{serviceType}/{serviceInstanceId}", method = RequestMethod.GET)
+ public AaiResponse<String> getVnfData(
+ @PathVariable("globalCustomerId") String globalCustomerId,
+ @PathVariable("serviceType") String serviceType,
+ @PathVariable("serviceInstanceId") String serviceInstanceId) {
+
+ return aaiService.getVNFData(globalCustomerId, serviceType, serviceInstanceId);
+
+ }
+
+
+ // @RequestMapping(value="/aai_get_tenants/{global-customer-id}", method = RequestMethod.GET)
+ // public ResponseEntity<String> viewEditGetComponentList(
+ // @PathVariable("global-customer-id") String globalCustomerId) {
+ // return new ResponseEntity<String>(getTenants(globalCustomerId), HttpStatus.OK);
+ // }
+
+ /**
+ * Issue a named query to a&ai.
+ *
+ * @param namedQueryId the named query id
+ * @param globalCustomerId the global customer id
+ * @param serviceType the service type
+ * @return ResponseEntity The response entity
+ */
+ @RequestMapping(value = "/aai_get_models_by_service_type/{namedQueryId}/{globalCustomerId}/{serviceType}", method = RequestMethod.GET)
+ public ResponseEntity<String> viewEditGetComponentList(
+ @PathVariable("namedQueryId") String namedQueryId,
+ @PathVariable("globalCustomerId") String globalCustomerId,
+ @PathVariable("serviceType") String serviceType) {
+
+ String componentListPayload = getModelsByServiceTypePayload(namedQueryId, globalCustomerId, serviceType);
+ File certiPath = GetCertificatesPath();
+
+ Response resp = doAaiPost(certiPath.getAbsolutePath(), "search/named-query", componentListPayload, false);
+ return convertResponseToResponseEntity(resp);
+ }
+
+ /**
+ * Parses the for tenants.
+ *
+ * @param resp the resp
+ * @return the string
+ */
+ private String parseForTenants(String resp) {
+ String tenantList = "";
+
+ try {
+ JSONParser jsonParser = new JSONParser();
+
+ JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
+
+ return parseCustomerObjectForTenants(jsonObject);
+ } catch (Exception ex) {
+
+ }
+
+ return tenantList;
+ }
+
+ /**
+ * Parses the for tenants by service subscription.
+ *
+ * @param resp the resp
+ * @return the string
+ */
+ private String parseForTenantsByServiceSubscription(String resp) {
+ String tenantList = "";
+
+ try {
+ JSONParser jsonParser = new JSONParser();
+
+ JSONObject jsonObject = (JSONObject) jsonParser.parse(resp);
+
+ return parseServiceSubscriptionObjectForTenants(jsonObject);
+ } catch (Exception ex) {
+
+ }
+
+ return tenantList;
+ }
+
+ /**
+ * Obtain tenants for a given service type.
+ *
+ * @param globalCustomerId the global customer id
+ * @param serviceType the service type
+ * @return ResponseEntity The response entity
+ */
+ @RequestMapping(value = "/aai_get_tenants/{global-customer-id}/{service-type}", method = RequestMethod.GET)
+ public ResponseEntity<String> viewEditGetTenantsFromServiceType(HttpServletRequest request,
+ @PathVariable("global-customer-id") String globalCustomerId, @PathVariable("service-type") String serviceType) {
+
+ ResponseEntity responseEntity;
+ try {
+ ObjectMapper objectMapper = new ObjectMapper();
+ List<Role> roles = new RoleProvider().getUserRoles(request);
+ RoleValidator roleValidator = new RoleValidator(roles);
+ AaiResponse<GetTenantsResponse[]> response = aaiService.getTenants(globalCustomerId, serviceType, roleValidator);
+ if (response.getHttpCode() == 200) {
+ responseEntity = new ResponseEntity<String>(objectMapper.writeValueAsString(response.getT()), HttpStatus.OK);
+ } else {
+ responseEntity = new ResponseEntity<String>(response.getErrorMessage(), HttpStatus.valueOf(response.getHttpCode()));
+ }
+ } catch (Exception e) {
+ responseEntity = new ResponseEntity<String>("Unable to proccess getTenants reponse", HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+ return responseEntity;
+ }
+
+
+ private ResponseEntity<String> convertResponseToResponseEntity(Response resp) {
+ ResponseEntity<String> respEnt;
+ ObjectMapper objectMapper = new ObjectMapper();
+ if (resp == null) {
+ respEnt = new ResponseEntity<String>("Failed to fetch data from A&AI, check server logs for details.", HttpStatus.INTERNAL_SERVER_ERROR);
+ } else {
+ respEnt = new ResponseEntity<String>(resp.readEntity(String.class), HttpStatus.valueOf(resp.getStatus()));
+ }
+ return respEnt;
+ }
+
+ /**
+ * Gets the tenants.
+ *
+ * @param globalCustomerId the global customer id
+ * @return the tenants
+ */
+ private ResponseEntity<String> getTenants(String globalCustomerId) {
+ File certiPath = GetCertificatesPath();
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + globalCustomerId, false);
+
+ ResponseEntity<String> respEnt;
+ if (resp.getStatus() >= 200 && resp.getStatus() <= 299) {
+ respEnt = new ResponseEntity<String>(parseForTenants((String) resp.readEntity(String.class)), HttpStatus.OK);
+ } else {
+ respEnt = new ResponseEntity<String>((String) resp.readEntity(String.class), HttpStatus.valueOf(resp.getStatus()));
+ }
+ return respEnt;
+
+ }
+
+ /**
+ * Gets the tenants from service type.
+ *
+ * @param globalCustomerId the global customer id
+ * @param serviceType the service type
+ * @return the tenants from service type
+ */
+ private ResponseEntity<String> getTenantsFromServiceType(String globalCustomerId, String serviceType) {
+
+
+ File certiPath = GetCertificatesPath();
+ String url = "business/customers/customer/" + globalCustomerId + "/service-subscriptions/service-subscription/" + serviceType;
+
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), url, false);
+
+ ResponseEntity<String> respEnt;
+ if (resp.getStatus() >= 200 && resp.getStatus() <= 299) {
+ respEnt = new ResponseEntity<String>(parseForTenantsByServiceSubscription((String) resp.readEntity(String.class)), HttpStatus.OK);
+ } else {
+ respEnt = new ResponseEntity<String>((String) resp.readEntity(String.class), HttpStatus.valueOf(resp.getStatus()));
+ }
+ return respEnt;
+
+ }
+
+ /**
+ * Gets the services.
+ *
+ * @return the services
+ */
+ private Response getServices() {
+ File certiPath = GetCertificatesPath();
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "service-design-and-creation/services", false);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getServices() resp=" + resp.getStatusInfo());
+
+ //model.put("aai_get_services", resp);
+ return resp;
+ }
+
+ /**
+ * Gets the subscribers.
+ *
+ * @param isFullSet the is full set
+ * @return the subscribers
+ */
+ private Response getSubscribers(boolean isFullSet) {
+
+ File certiPath = GetCertificatesPath();
+ String depth = "0";
+
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers?subscriber-type=INFRA&depth=" + depth, false);
+ if (resp != null) {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscribers() resp=" + resp.getStatusInfo().toString());
+ }
+ return resp;
+ }
+
+ /**
+ * Gets the subscriber details.
+ *
+ * @param subscriberId the subscriber id
+ * @return the subscriber details
+ */
+ private Response getSubscriberDetails(String subscriberId) {
+ File certiPath = GetCertificatesPath();
+ Response resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + subscriberId + "?depth=2", false);
+ //String resp = doAaiGet(certiPath.getAbsolutePath(), "business/customers/customer/" + subscriberId, false);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "getSubscriberDetails() resp=" + resp.getStatusInfo().toString());
+ return resp;
+ }
+
+ /**
+ * Gets the certificates path.
+ *
+ * @return the file
+ */
+ private File GetCertificatesPath() {
+ if (servletContext != null)
+ return new File(servletContext.getRealPath("/WEB-INF/cert/"));
+ return null;
+ }
+
+ /**
+ * Send a GET request to a&ai.
+ *
+ * @param certiPath the certi path
+ * @param uri the uri
+ * @param xml the xml
+ * @return String The response
+ */
+ protected Response doAaiGet(String certiPath, String uri, boolean xml) {
+ String methodName = "getSubscriberList";
+ String transId = UUID.randomUUID().toString();
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ Response resp = null;
+ try {
+
+ AAIRestInterface restContrller = new AAIRestInterface(certiPath);
+ resp = restContrller.RestGet(fromAppId, transId, uri, xml);
+
+ } catch (WebApplicationException e) {
+ final String message = ((BadRequestException) e).getResponse().readEntity(String.class);
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + message);
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ }
+
+ return resp;
+ }
+
+ /**
+ * Send a POST request to a&ai.
+ *
+ * @param certiPath the certi path
+ * @param uri the uri
+ * @param payload the payload
+ * @param xml the xml
+ * @return String The response
+ */
+ protected Response doAaiPost(String certiPath, String uri, String payload, boolean xml) {
+ String methodName = "getSubscriberList";
+ String transId = UUID.randomUUID().toString();
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ Response resp = null;
+ try {
+
+ AAIRestInterface restContrller = new AAIRestInterface(certiPath);
+ resp = restContrller.RestPost(fromAppId, transId, uri, payload, xml);
+
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ }
+
+ return resp;
+ }
+
+ /**
+ * Gets the component list put payload.
+ *
+ * @param namedQueryId the named query id
+ * @param globalCustomerId the global customer id
+ * @param serviceType the service type
+ * @param serviceInstance the service instance
+ * @return the component list put payload
+ */
+ private String getComponentListPutPayload(String namedQueryId, String globalCustomerId, String serviceType, String serviceInstance) {
+ return
+ " {" +
+ " \"instance-filters\": {" +
+ " \"instance-filter\": [" +
+ " {" +
+ " \"customer\": {" +
+ " \"global-customer-id\": \"" + globalCustomerId + "\"" +
+ " }," +
+ " \"service-instance\": {" +
+ " \"service-instance-id\": \"" + serviceInstance + "\"" +
+ " }," +
+ " \"service-subscription\": {" +
+ " \"service-type\": \"" + serviceType + "\"" +
+ " }" +
+ " }" +
+ " ]" +
+ " }," +
+ " \"query-parameters\": {" +
+ " \"named-query\": {" +
+ " \"named-query-uuid\": \"" + namedQueryId + "\"" +
+ " }" +
+ " }" +
+ "}";
+
+ }
+
+ private String getModelsByServiceTypePayload(String namedQueryId, String globalCustomerId, String serviceType) {
+ // TODO Auto-generated method stub
+ return " {" +
+ " \"instance-filters\": {" +
+ " \"instance-filter\": [" +
+ " {" +
+ " \"customer\": {" +
+ " \"global-customer-id\": \"" + globalCustomerId + "\"" +
+ " }," +
+ " \"service-subscription\": {" +
+ " \"service-type\": \"" + serviceType + "\"" +
+ " }" +
+ " }" +
+ " ]" +
+ " }," +
+ " \"query-parameters\": {" +
+ " \"named-query\": {" +
+ " \"named-query-uuid\": \"" + namedQueryId + "\"" +
+ " }" +
+ " }" +
+ "}";
+
+ }
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/ChangeManagementController.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/ChangeManagementController.java
new file mode 100644
index 000000000..1af715464
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/ChangeManagementController.java
@@ -0,0 +1,71 @@
+package org.openecomp.vid.controller;
+
+import org.json.simple.JSONArray;
+import org.openecomp.portalsdk.core.controller.UnRestrictedBaseController;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.services.ChangeManagementService;
+import org.openecomp.vid.services.WorkflowService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
+import org.openecomp.vid.mso.rest.Request;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Controller to handle ChangeManagement feature requests.
+ */
+@RestController
+@RequestMapping("change-management")
+public class ChangeManagementController extends UnRestrictedBaseController {
+ private EELFLoggerDelegate logger;
+ private String fromAppId;
+ private final WorkflowService workflowService;
+ private final ChangeManagementService changeManagementService;
+
+ @Autowired
+ public ChangeManagementController(WorkflowService workflowService, ChangeManagementService changeManagementService) {
+ this.logger = EELFLoggerDelegate.getLogger(ChangeManagementController.class);
+ this.fromAppId = "VidChangeManagementController";
+ this.workflowService = workflowService;
+ this.changeManagementService = changeManagementService;
+ }
+
+ @RequestMapping(value = {"/workflow"}, method = RequestMethod.GET)
+ public ResponseEntity<Collection<String>> getWorkflow(@RequestParam("vnfs") Collection<String> vnfs) throws IOException, InterruptedException {
+ Collection<String> result = this.workflowService.getWorkflowsForVNFs(vnfs);
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ }
+
+ @RequestMapping(value = {"/mso"}, method = RequestMethod.GET)
+ public ResponseEntity<Collection<Request>> getMSOChangeManagements() throws IOException, InterruptedException {
+ Collection<Request> result = this.changeManagementService.getMSOChangeManagements();
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ }
+
+ @RequestMapping(value = "/workflow/{vnfName}", method = RequestMethod.POST)
+ public ResponseEntity<String> changeManagement(@PathVariable("vnfName") String vnfName,
+ HttpServletRequest request,
+ @RequestBody ChangeManagementRequest changeManagmentRequest)
+ throws Exception {
+ return this.changeManagementService.doChangeManagement(changeManagmentRequest, vnfName);
+ }
+
+
+ @RequestMapping(value = {"/scheduler"}, method = RequestMethod.GET)
+ public ResponseEntity<JSONArray> getSchedulerChangeManagements() throws IOException, InterruptedException {
+ JSONArray result = this.changeManagementService.getSchedulerChangeManagements();
+ return new ResponseEntity<>(result, HttpStatus.OK);
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoConfig.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoConfig.java
new file mode 100644
index 000000000..e0b59204a
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoConfig.java
@@ -0,0 +1,29 @@
+package org.openecomp.vid.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.openecomp.vid.factories.MsoRequestFactory;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class MsoConfig {
+
+ /**
+ * Gets the object mapper.
+ *
+ * @return the object mapper
+ */
+ @Bean
+ public ObjectMapper getObjectMapper() {
+ return new ObjectMapper();
+ }
+
+ @Bean
+ public MsoRequestFactory createRequestDetailsFactory(){
+ return new MsoRequestFactory();
+ }
+
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoController.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoController.java
index 56fbd4cbd..9a064b000 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoController.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/MsoController.java
@@ -21,35 +21,56 @@
package org.openecomp.vid.controller;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.glassfish.jersey.client.ClientResponse;
-import org.json.simple.JSONArray;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
-import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
-import org.openecomp.portalsdk.core.util.SystemProperties;
-import org.openecomp.vid.model.ExceptionResponse;
-import org.openecomp.vid.mso.*;
-import org.openecomp.vid.mso.rest.RequestDetails;
-import org.openecomp.vid.roles.RoleProvider;
-import org.openecomp.vid.roles.RoleValidator;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
+import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+//import java.util.UUID;
import java.util.Date;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Scanner;
+import java.util.stream.Collectors;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.codehaus.jackson.JsonEncoding;
+import org.codehaus.jackson.JsonFactory;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.glassfish.jersey.client.ClientResponse;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.openecomp.vid.model.ExceptionResponse;
+import org.openecomp.vid.mso.*;
+import org.openecomp.vid.mso.rest.*;
+import org.springframework.http.HttpStatus;
+//import org.springframework.http.ResponseEntity;
+//import org.springframework.http.RequestEntity;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.servlet.ModelAndView;
+
+import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectReader;
+import com.fasterxml.jackson.databind.DeserializationFeature;
/**
* The Class MsoController.
@@ -59,25 +80,30 @@ import java.util.Map;
public class MsoController extends RestrictedBaseController {
/**
- * The Constant SVC_INSTANCE_ID.
+ * The view name.
*/
- public final static String SVC_INSTANCE_ID = "<service_instance_id>";
+ String viewName;
+
/**
- * The Constant VNF_INSTANCE_ID.
+ * The logger.
*/
- public final static String VNF_INSTANCE_ID = "<vnf_instance_id>";
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoController.class);
+
/**
* The Constant dateFormat.
*/
final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
/**
- * The view name.
+ * The Constant SVC_INSTANCE_ID.
*/
- String viewName;
+ public final static String SVC_INSTANCE_ID = "<service_instance_id>";
+ public final static String REQUEST_TYPE = "<request_type>";
+
/**
- * The logger.
+ * The Constant VNF_INSTANCE_ID.
*/
- EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoController.class);
+ public final static String VNF_INSTANCE_ID = "<vnf_instance_id>";
/**
* Welcome.
@@ -118,37 +144,70 @@ public class MsoController extends RestrictedBaseController {
*/
@RequestMapping(value = "/mso_create_svc_instance", method = RequestMethod.POST)
public ResponseEntity<String> createSvcInstance(HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
+ String methodName = "createSvcInstance";
+
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+ // always return OK, the MSO status code is embedded in the body
+
+ MsoResponseWrapper w = mbl.createSvcInstance(mso_request);
+
+ return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
+
+ }
+ /**
+ * Creates the svc instance.
+ *
+ * @param request the request
+ * @return the response entity
+ * @throws Exception the exception
+ */
+
+ public ResponseEntity<String> createSvcInstanceNewRest(HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
String methodName = "createSvcInstance";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
-// mso_request = retrieveRequestObject (request, mso_request);
+ MsoBusinessLogicNew mbln = new MsoBusinessLogicNew();
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
- String userId = "";
- HttpSession session = request.getSession();
- System.out.println((new ObjectMapper().writeValueAsString(session.getAttribute("roles"))));
- MsoResponseWrapper w = createInstance(mso_request, p);
- return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
// always return OK, the MSO status code is embedded in the body
+ MsoResponseWrapper w = mbln.createSvcInstanceRest(mso_request);
+
+ if (w == null) {
+ return null;
+ }
+ return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
}
- private boolean userIsPermmited(HttpServletRequest request, RequestDetails mso_request) {
+ /**
+ * Creates the svc instance.
+ *
+ * @param request the request
+ * @return the response entity
+ * @throws Exception the exception
+ */
+
+ public ResponseEntity<String> createSvcInstanceNew(HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
+ String methodName = "createSvcInstance";
+
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ MsoBusinessLogicNew mbln = new MsoBusinessLogicNew();
+ // always return OK, the MSO status code is embedded in the body
+
+ MsoResponseWrapper w = mbln.createSvcInstance(mso_request);
- RoleValidator roleValidator = new RoleValidator(new RoleProvider().getUserRoles(request));
- boolean isPermitted = roleValidator.isMsoRequestValid(mso_request);
- if (!isPermitted) {
- return false;
- } else {
- return true;
+ if (w == null) {
+ return null;
}
+
+ return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
+
}
/**
@@ -161,23 +220,10 @@ public class MsoController extends RestrictedBaseController {
*/
@RequestMapping(value = "/mso_create_vnf_instance/{serviceInstanceId}", method = RequestMethod.POST)
public ResponseEntity<String> createVnf(@PathVariable("serviceInstanceId") String serviceInstanceId, HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
-// if (!userIsPermmited(request, mso_request)) {
- String instanceId = (String) ((Map)((Map)((ArrayList)((Map) mso_request.getAdditionalProperties().get("requestDetails")).get("relatedInstanceList")).get(0)).get("relatedInstance")).get("instanceId");
- ResponseEntity<String> a = new AaiController(request.getServletContext()).doGetServiceInstance(instanceId,"Service Instance id");
-// return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
-// }
- String methodName = "createVnf";
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- //RequestDetails mso_request = retrieveRequestObject (request);
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_VNF_INSTANCE);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
- if (p == null || p.isEmpty()) {
- throw new Exception("Vnf instance path is not defined");
- }
- // /serviceInstances/v2/<service_instance_id>/vnfs
- String vnf_path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- MsoResponseWrapper w = createInstance(mso_request, vnf_path);
+ MsoResponseWrapper w = mbl.createVnf(mso_request, serviceInstanceId);
// always return OK, the MSO status code is embedded in the body
@@ -195,23 +241,12 @@ public class MsoController extends RestrictedBaseController {
*/
@RequestMapping(value = "/mso_create_nw_instance/{serviceInstanceId}", method = RequestMethod.POST)
public ResponseEntity<String> createNwInstance(@PathVariable("serviceInstanceId") String serviceInstanceId, HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
-
String methodName = "createNwInstance";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start, serviceInstanceId = " + serviceInstanceId);
- //RequestDetails mso_request = retrieveRequestObject (request);
-
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
-
- if (p == null || p.isEmpty()) {
- throw new Exception("Network instance path is not defined");
- }
- // /serviceInstances/v2/<serviceInstanceId>/networks/
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
- String nw_path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- MsoResponseWrapper w = createInstance(mso_request, nw_path);
-
- // always return OK, the MSO status code is embedded in the body
+ MsoResponseWrapper w = mbl.createNwInstance(mso_request, serviceInstanceId);
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
@@ -230,21 +265,11 @@ public class MsoController extends RestrictedBaseController {
public ResponseEntity<String> createVolumeGroupInstance(@PathVariable("serviceInstanceId") String serviceInstanceId, @PathVariable("vnfInstanceId") String vnfInstanceId,
HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
String methodName = "createVolumeGroupInstance";
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- //RequestDetails mso_request = retrieveRequestObject (request);
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
- if (p == null || p.isEmpty()) {
- throw new Exception("Volume group instance path is not defined");
- }
- String path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- path = path.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
-
- MsoResponseWrapper w = createInstance(mso_request, path);
+ MsoResponseWrapper w = mbl.createVolumeGroupInstance(mso_request, serviceInstanceId, vnfInstanceId);
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
@@ -265,40 +290,31 @@ public class MsoController extends RestrictedBaseController {
String methodName = "createVfModuleInstance";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
- //RequestDetails mso_request = retrieveRequestObject (request);
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
- if (p == null || p.isEmpty()) {
- throw new Exception("VF module instance path is not defined");
- }
- // /serviceInstances/v2/<serviceInstanceId>/vnfs/<vnfInstanceId>/vfmodules
- String path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- path = path.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
- MsoResponseWrapper w = createInstance(mso_request, path);
+ MsoResponseWrapper w = mbl.createVfModuleInstance(mso_request, serviceInstanceId, vnfInstanceId);
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
}
- /**
- * Creates the instance.
- *
- * @param request the request
- * @param path the path
- * @return the mso response wrapper
- * @throws Exception the exception
- */
- protected MsoResponseWrapper createInstance(RequestDetails request, String path) throws Exception {
- String methodName = "createInstance";
- logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+ /**
+ * Creates the instance.
+ *
+ * @param request the request
+ * @param path the path
+ * @return the mso response wrapper
+ * @throws ClientHandlerException the client handler exception
+ * @throws Exception the exception
+ */
+ protected MsoResponseWrapper createInstance(RequestDetails request, String path) throws Exception {
+ String methodName = "createInstance";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
try {
- MsoRestInterfaceIfc restController = MsoRestInterfaceFactory.getInstance();
+ MsoRestInterfaceIfc restController = new MsoRestInterface();
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " calling Post, request = (" + request + ")");
RestObject<String> restObjStr = new RestObject<String>();
@@ -307,14 +323,14 @@ public class MsoController extends RestrictedBaseController {
restController.<String>Post(str, request, "", path, restObjStr);
MsoResponseWrapper w = MsoUtil.wrapResponse(restObjStr);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
- return w;
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- throw e;
- }
- }
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+ return w;
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
/**
* Delete svc instance.
@@ -331,10 +347,9 @@ public class MsoController extends RestrictedBaseController {
String methodName = "deleteSvcInstance";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- //RequestDetails mso_request = retrieveRequestObject (request);
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
- String path = p + "/" + serviceInstanceId;
- MsoResponseWrapper w = deleteInstance(mso_request, path);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.deleteSvcInstance(mso_request, serviceInstanceId);
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
// always return OK, the MSO status code is embedded in the body
@@ -359,17 +374,10 @@ public class MsoController extends RestrictedBaseController {
String methodName = "deleteVnf";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
- //RequestDetails mso_request = retrieveRequestObject (request);
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_VNF_INSTANCE);
- if (p == null || p.isEmpty()) {
- throw new Exception("Vnf instance path is not defined");
- }
- // /serviceInstances/v2/<service_instance_id>/vnfs/
- String vnf_path = p.replaceFirst(SVC_INSTANCE_ID, vnfInstanceId);
- MsoResponseWrapper w = deleteInstance(mso_request, vnf_path + "/" + vnfInstanceId);
+
+ MsoBusinessLogic mlb = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mlb.deleteVnf(mso_request, serviceInstanceId, vnfInstanceId);
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
@@ -393,21 +401,11 @@ public class MsoController extends RestrictedBaseController {
@PathVariable("vfModuleId") String vfModuleId, HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
String methodName = "deleteVfModule";
-
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
- //RequestDetails mso_request = new RequestDetails();
- //mso_request = retrieveRequestObject (request);
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
- if (p == null || p.isEmpty()) {
- throw new Exception("VF Module instance path is not defined");
- }
- // /serviceInstances/v2/<serviceInstanceId>/vnfs/<vnfInstanceId>/vfmodules
- String path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- path = path.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
- MsoResponseWrapper w = deleteInstance(mso_request, path + "/" + vfModuleId);
+
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.deleteVfModule(mso_request, serviceInstanceId, vnfInstanceId);
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
@@ -428,21 +426,12 @@ public class MsoController extends RestrictedBaseController {
public ResponseEntity<String> deleteVolumeGroupInstance(
@PathVariable("serviceInstanceId") String serviceInstanceId, @PathVariable("vnfInstanceId") String vnfInstanceId, @PathVariable("volumeGroupId") String volumeGroupId,
HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
-
String methodName = "deleteVolumeGroupInstance";
-
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
- if (p == null || p.isEmpty()) {
- throw new Exception("Volume group instance path is not defined");
- }
- // /serviceInstances/v2/{serviceInstanceId}/volumeGroups
- String path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- path = path.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
- MsoResponseWrapper w = deleteInstance(mso_request, path + "/" + volumeGroupId);
+
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.deleteVolumeGroupInstance(mso_request, serviceInstanceId, vnfInstanceId, volumeGroupId);
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
@@ -460,21 +449,12 @@ public class MsoController extends RestrictedBaseController {
@RequestMapping(value = "/mso_delete_nw_instance/{serviceInstanceId}/networks/{networkInstanceId}", method = RequestMethod.POST)
public ResponseEntity<String> deleteNwInstance(@PathVariable("serviceInstanceId") String serviceInstanceId,
@PathVariable("networkInstanceId") String networkInstanceId, HttpServletRequest request, @RequestBody RequestDetails mso_request) throws Exception {
-
String methodName = "deleteNwInstance";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- //RequestDetails mso_request = retrieveRequestObject (request);
- if (!userIsPermmited(request, mso_request)) {
- return new ResponseEntity<String>(HttpStatus.FORBIDDEN);
- }
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
- if (p == null || p.isEmpty()) {
- throw new Exception("Network instance path is not defined");
- }
- // /serviceInstances/v2/<service_instance_id>/networks
- String path = p.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
- MsoResponseWrapper w = deleteInstance(mso_request, path + "/" + networkInstanceId);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.deleteNwInstance(mso_request, serviceInstanceId, networkInstanceId);
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
@@ -482,39 +462,6 @@ public class MsoController extends RestrictedBaseController {
}
/**
- * Delete instance.
- *
- * @param request the request
- * @param path the path
- * @return the mso response wrapper
- * @throws Exception the exception
- */
- protected MsoResponseWrapper deleteInstance(RequestDetails request, String path) throws Exception {
- String methodName = "deleteInstance";
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
-
- try {
- MsoRestInterfaceIfc restController = MsoRestInterfaceFactory.getInstance();
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " calling Delete, path =[" + path + "]");
-
- RestObject<String> restObjStr = new RestObject<String>();
- String str = new String();
- restObjStr.set(str);
- restController.<String>Delete(str, request, "", path, restObjStr);
- MsoResponseWrapper w = MsoUtil.wrapResponse(restObjStr);
-
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
- return w;
-
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- throw e;
- }
-
- }
-
- /**
* Gets the orchestration request.
*
* @param requestId the request id
@@ -528,27 +475,12 @@ public class MsoController extends RestrictedBaseController {
String methodName = "getOrchestrationRequest";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- MsoResponseWrapper w = null;
- try {
- MsoRestInterfaceIfc restController = MsoRestInterfaceFactory.getInstance();
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQ);
- String path = p + "/" + requestId;
- RestObject<String> restObjStr = new RestObject<String>();
- String str = new String();
- restObjStr.set(str);
- restController.<String>Get(str, "", path, restObjStr);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
- w = MsoUtil.wrapResponse(restObjStr);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
- // always return OK, the MSO status code is embedded in the body
+ MsoResponseWrapper w = mbl.getOrchestrationRequest(requestId);
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- throw e;
- }
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
}
@@ -568,63 +500,134 @@ public class MsoController extends RestrictedBaseController {
String methodName = "getOrchestrationRequests";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- MsoResponseWrapper w = null;
- try {
- MsoRestInterfaceIfc restController = MsoRestInterfaceFactory.getInstance();
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
- String path = p + filterString;
- RestObject<String> restObjStr = new RestObject<String>();
- String str = new String();
- restObjStr.set(str);
- restController.<String>Get(str, "", path, restObjStr);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.getOrchestrationRequests(filterString);
- w = MsoUtil.wrapResponse(restObjStr);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- throw e;
- }
// always return OK, the MSO status code is embedded in the body
return (new ResponseEntity<String>(w.getResponse(), HttpStatus.OK));
}
+
/**
- * Gets the orchestration requests for svc instance.
+ * activate to a pnf instance.
*
- * @param svc_instance_id the svc instance id
- * @return the orchestration requests for svc instance
+ * @param serviceInstanceId the id of the service.
+ * @param requestDetails the body of the request.
+ * @return the response entity
* @throws Exception the exception
*/
- public MsoResponseWrapper getOrchestrationRequestsForSvcInstance(String svc_instance_id) throws Exception {
+ @RequestMapping(value = "/mso_activate_service_instance/{serviceInstanceId}", method = RequestMethod.POST)
+ public ResponseEntity<String> activateServiceInstance(@PathVariable("serviceInstanceId") String serviceInstanceId, @RequestBody RequestDetails requestDetails) throws Exception {
+ String methodName = "activateServiceInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.activateServiceInstance(requestDetails, serviceInstanceId);
+ return new ResponseEntity<>(w.getResponse(), HttpStatus.OK);
+ }
+
- String methodName = "getOrchestrationRequestsForSvcInstance";
+ /**
+ * Gets the orchestration requests for the dashboard.
+ * currently its all the orchestration requests with RequestType updateInstance or replaceInstance.
+ * @return the orchestration requests
+ * @throws Exception the exception
+ */
+ @RequestMapping(value = "/mso_get_orch_reqs/dashboard", method = RequestMethod.GET)
+ public List<Request> getOrchestrationRequestsForDashboard() throws Exception {
+
+ String methodName = "getOrchestrationRequestsForDashboard";
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
- MsoResponseWrapper w = null;
- try {
- MsoRestInterfaceIfc restController = MsoRestInterfaceFactory.getInstance();
- String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
- String path = p + svc_instance_id;
- RestObject<String> restObjStr = new RestObject<String>();
- String str = new String();
- restObjStr.set(str);
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
- restController.<String>Get(str, "", path, restObjStr);
- w = MsoUtil.wrapResponse(restObjStr);
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+ return mbl.getOrchestrationRequestsForDashboard();
+ }
- } catch (Exception e) {
- logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
- throw e;
- }
- return w;
+ /**
+ * Gets the Manual Tasks for the given request id.
+ *
+ * @param originalRequestId the id of the original request.
+ * @return the tasks
+ * @throws Exception the exception
+ */
+ @RequestMapping(value = "/mso_get_man_task/{originalRequestId}", method = RequestMethod.GET)
+ public List<Task> getManualTasksByRequestId(@PathVariable("originalRequestId") String originalRequestId) throws Exception {
+
+ String methodName = "getManualTasksByRequestId";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ return mbl.getManualTasksByRequestId(originalRequestId);
+ }
+
+
+
+ /**
+ * Complete the manual task.
+ *
+ * @param taskId the id of the task to complete.
+ * @param requestDetails the body of the request.
+ * @return the response entity
+ * @throws Exception the exception
+ */
+ @RequestMapping(value = "/mso_post_man_task/{taskId}", method = RequestMethod.POST)
+ public ResponseEntity<String> manualTaskComplete(@PathVariable("taskId") String taskId , @RequestBody RequestDetails requestDetails) throws Exception {
+
+ String methodName = "manualTaskComplete";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ MsoBusinessLogic mbl = new MsoBusinessLogic();
+
+ MsoResponseWrapper w = mbl.completeManualTask(requestDetails, taskId);
+ return new ResponseEntity<String>(w.getResponse(), HttpStatus.OK);
}
+
+
+
+
+ /**
+ * Gets the orchestration requests for svc instance.
+ *
+ * @param svc_instance_id the svc instance id
+ * @return the orchestration requests for svc instance
+ * @throws Exception the exception
+ */
+// public MsoResponseWrapper getOrchestrationRequestsForSvcInstance(String svc_instance_id) throws Exception {
+
+// String methodName = "getOrchestrationRequestsForSvcInstance";
+// logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+// MsoResponseWrapper w = null;
+//
+// try {
+// MsoRestInterfaceIfc restController = MsoRestInterfaceFactory.getInstance();
+// String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
+// String path = p + svc_instance_id;
+//
+// RestObject<String> restObjStr = new RestObject<String>();
+// String str = new String();
+// restObjStr.set(str);
+//
+// restController.<String>Get(str, "", path, restObjStr);
+// w = MsoUtil.wrapResponse(restObjStr);
+// logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+//
+// } catch (Exception e) {
+// logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+// logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+// throw e;
+// }
+// return w;
+// }
+
/**
* Exception handler.
*
@@ -636,7 +639,7 @@ public class MsoController extends RestrictedBaseController {
private void exceptionHandler(Exception e, HttpServletResponse response) throws IOException {
/*
- * The following "logger.error" lines "should" be sufficient for logging the exception.
+ * The following "logger.error" lines "should" be sufficient for logging the exception.
* However, the console output in my Eclipse environment is NOT showing ANY of the
* logger statements in this class. Thus the temporary "e.printStackTrace" statement
* is also included.
@@ -649,7 +652,7 @@ public class MsoController extends RestrictedBaseController {
logger.error(EELFLoggerDelegate.errorLogger, sw.toString());
/*
- * Temporary - IF the above mentioned "logger.error" glitch is resolved ...
+ * Temporary - IF the above mentioned "logger.error" glitch is resolved ...
* this statement could be removed since it would then likely result in duplicate
* trace output.
*/
@@ -673,7 +676,8 @@ public class MsoController extends RestrictedBaseController {
*
* @param resp the resp
* @return the list
- * @throws Exception the exception
+ * @throws ParseException the parse exception
+ * @throws Exception the exception
*/
@SuppressWarnings("unchecked")
public List<JSONObject> parseOrchestrationRequestsForSvcInstance(ClientResponse resp) throws org.json.simple.parser.ParseException, Exception {
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/PolicyController.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/PolicyController.java
new file mode 100644
index 000000000..83e177a61
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/PolicyController.java
@@ -0,0 +1,90 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.controller;
+
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.json.simple.JSONObject;
+import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.policy.PolicyProperties;
+import org.openecomp.vid.policy.PolicyResponseWrapper;
+import org.openecomp.vid.policy.PolicyRestInterfaceFactory;
+import org.openecomp.vid.policy.PolicyRestInterfaceIfc;
+import org.openecomp.vid.policy.PolicyUtil;
+import org.openecomp.vid.policy.RestObject;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Controller to handle Policy requests.
+ */
+
+@RestController
+public class PolicyController extends RestrictedBaseController{
+
+ /** The logger. */
+ static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PolicyController.class);
+
+ @RequestMapping(value="/get_policy",method = RequestMethod.POST)
+ public ResponseEntity<String> getPolicyInfo( HttpServletRequest request, @RequestBody JSONObject policy_request) throws Exception {
+
+ logger.debug("#####################POLICY API CALL STARTED ###############"+ PolicyProperties.POLICY_GET_CONFIG_VAL);
+ logger.debug("#####################Policy Request ###############"+policy_request.toString());
+
+ String path = PolicyProperties.getProperty(PolicyProperties.POLICY_GET_CONFIG_VAL);
+ PolicyResponseWrapper policyResWrapper = getPolicyConfig(policy_request,path);
+
+ logger.debug("$$$$$$$$$$$$$$$$$$$$$$ " + new ResponseEntity<String>(policyResWrapper.getResponse(), HttpStatus.OK).toString());
+
+ return ( new ResponseEntity<String>(policyResWrapper.getResponse(), HttpStatus.valueOf(policyResWrapper.getStatus())) );
+ }
+
+ protected static PolicyResponseWrapper getPolicyConfig(JSONObject request, String path) throws Exception {
+ String methodName = "getPolicyConfig";
+ String uuid = UUID.randomUUID().toString();
+ logger.debug( "starting getPolicyConfig ");
+
+ try {
+ //STARTING REST API CALL AS AN FACTORY INSTACE
+ PolicyRestInterfaceIfc restController = PolicyRestInterfaceFactory.getInstance();
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+ restController.<String>Post(str, request, uuid, path, restObjStr );
+ PolicyResponseWrapper policyRespWrapper = PolicyUtil.wrapResponse (restObjStr);
+
+ logger.debug( "<== " + methodName + " w=" + policyRespWrapper.getResponse());
+ return policyRespWrapper;
+ } catch (Exception e) {
+ logger.debug( "EXCEPTION in getPolicyConfig <== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+}
+
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/SchedulerController.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/SchedulerController.java
new file mode 100644
index 000000000..0fd2079e9
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/SchedulerController.java
@@ -0,0 +1,244 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.controller;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.json.simple.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.scheduler.RestObjects.GetTimeSlotsRestObject;
+import org.openecomp.vid.scheduler.RestObjects.PostCreateNewVnfRestObject;
+import org.openecomp.vid.scheduler.RestObjects.PostSubmitVnfChangeRestObject;
+import org.openecomp.vid.scheduler.SchedulerProperties;
+import org.openecomp.vid.scheduler.SchedulerRestInterface;
+import org.openecomp.vid.scheduler.SchedulerResponseWrappers.GetTimeSlotsWrapper;
+import org.openecomp.vid.scheduler.SchedulerResponseWrappers.PostCreateNewVnfWrapper;
+import org.openecomp.vid.scheduler.SchedulerResponseWrappers.PostSubmitVnfChangeTimeSlotsWrapper;
+import org.openecomp.vid.scheduler.SchedulerUtil;
+
+/**
+ * Controller to handle Scheduler requests.
+ */
+
+@RestController
+public class SchedulerController extends RestrictedBaseController {
+
+ static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerController.class);
+
+ /** The request date format. */
+ public DateFormat requestDateFormat = new SimpleDateFormat("EEE, dd MMM YYYY HH:mm:ss z");
+
+ @Autowired
+ private SchedulerRestInterface restController;
+
+ /*
+ *
+ * GET SCHEDULER CONTROLLERS
+ *
+ */
+
+ @RequestMapping(value = "/get_time_slots/{scheduler_request}", method = RequestMethod.GET)
+ public ResponseEntity<String> getTimeSlots(HttpServletRequest request, @PathVariable("scheduler_request") String scheduler_request) throws Exception {
+
+ Date startingTime = new Date();
+ String startTimeRequest = requestDateFormat.format(startingTime);
+
+ System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+ System.out.println(startTimeRequest + " | Controller Scheduler GET : /get_time_slots/{scheduler_request} \n");
+ System.out.println("Original Request : \n " + scheduler_request + '\n');
+
+ String path = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_GET_TIME_SLOTS) + scheduler_request;
+
+ GetTimeSlotsWrapper schedulerResWrapper = getTimeSlots(scheduler_request, path, scheduler_request);
+
+ Date endTime = new Date();
+ String endTimeRequest = requestDateFormat.format(endTime);
+ System.out.println(endTimeRequest + " | Controller Scheduler - GET\n");
+
+ return (new ResponseEntity<String>(schedulerResWrapper.getResponse(), HttpStatus.OK));
+
+ }
+
+ protected GetTimeSlotsWrapper getTimeSlots(String request, String path, String uuid) throws Exception {
+
+ try {
+ //STARTING REST API CALL AS AN FACTORY INSTACE
+ System.out.println("<== Get Time Slots Request START \n");
+
+ GetTimeSlotsRestObject<String> restObjStr = new GetTimeSlotsRestObject<String>();
+ String str = new String();
+
+ restObjStr.set(str);
+
+ restController.<String>Get(str, uuid, path, restObjStr);
+ GetTimeSlotsWrapper schedulerRespWrapper = SchedulerUtil.getTimeSlotsWrapResponse(restObjStr);
+
+ System.out.println("<== Get Time Slots Request END : Response = " + schedulerRespWrapper.getResponse() + '\n');
+
+ return schedulerRespWrapper;
+
+ } catch (Exception e) {
+ System.out.println("<== Get Time Slots Request ERROR : " + e.toString() + '\n');
+ throw e;
+ }
+ }
+
+ /*
+ *
+ * POST SCHEDULER CONTROLLERS
+ *
+ */
+
+ @SuppressWarnings("unchecked")
+ @RequestMapping(value = "/post_create_new_vnf_change", method = RequestMethod.POST)
+ public ResponseEntity<String> postCreateNewVNFChange(HttpServletRequest request, @RequestBody JSONObject scheduler_request) throws Exception {
+
+ Date startingTime = new Date();
+ String startTimeRequest = requestDateFormat.format(startingTime);
+
+ System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+ System.out.println(startTimeRequest + " | Controller Scheduler POST : post_create_new_vnf_change \n");
+
+ //Generating uuid
+ String uuid = UUID.randomUUID().toString();
+
+ scheduler_request.put("scheduleId", uuid);
+ System.out.println("<== UUID : " + uuid + '\n');
+
+ //adding uuid to the request payload
+ scheduler_request.put("scheduleId", uuid);
+
+ System.out.println("<== UUID : " + uuid + '\n');
+ System.out.println("Original Request : \n " + scheduler_request.toString() + '\n');
+
+ String path = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_CREATE_NEW_VNF_CHANGE_INSTANCE_VAL) + uuid;
+
+ PostCreateNewVnfWrapper responseWrapper = postSchedulingRequest(scheduler_request, path, uuid);
+
+ Date endTime = new Date();
+ String endTimeRequest = requestDateFormat.format(endTime);
+ System.out.println(endTimeRequest + " | Controller Scheduler - POST\n");
+
+ return (new ResponseEntity<String>(responseWrapper.getResponse(), HttpStatus.OK));
+ }
+
+ protected PostCreateNewVnfWrapper postSchedulingRequest(JSONObject request, String path, String uuid) throws Exception {
+
+ try {
+ //STARTING REST API CALL AS AN FACTORY INSTACE
+ System.out.println("<== Post Create New Vnf Scheduling Request START \n");
+
+ PostCreateNewVnfRestObject<String> restObjStr = new PostCreateNewVnfRestObject<String>();
+ String str = new String();
+
+ restObjStr.set(str);
+ restController.<String>Post(str, request, path, restObjStr);
+
+ int status = restObjStr.getStatusCode();
+ if (status >= 200 && status <= 299) {
+ restObjStr.setUUID(uuid);
+ }
+
+ PostCreateNewVnfWrapper responseWrapper = SchedulerUtil.postCreateNewVnfWrapResponse(restObjStr);
+
+ System.out.println("<== Post Create New Vnf Scheduling Request END : Response = " + responseWrapper.getResponse() + '\n');
+
+ return responseWrapper;
+
+ } catch (Exception e) {
+ System.out.println("<== Post Create New Vnf Scheduling Request ERROR : " + e.toString() + '\n');
+ throw e;
+ }
+ }
+
+ @RequestMapping(value = "/submit_vnf_change_timeslots", method = RequestMethod.POST)
+ public ResponseEntity<String> postSubmitVnfChangeTimeslots(HttpServletRequest request, @RequestBody JSONObject scheduler_request) throws Exception {
+
+ Date startingTime = new Date();
+ String startTimeRequest = requestDateFormat.format(startingTime);
+
+ System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
+ System.out.println(startTimeRequest + " | Controller Scheduler POST : submit_vnf_change_timeslots \n");
+
+ //Generating uuid
+ String uuid = (String) scheduler_request.get("scheduleId");
+ scheduler_request.remove("scheduleId");
+
+ System.out.println("<== UUID : " + uuid + '\n');
+ System.out.println("Original Request : \n " + scheduler_request.toString() + '\n');
+
+ String path = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_SUBMIT_NEW_VNF_CHANGE).replace("{scheduleId}", uuid);
+
+ PostSubmitVnfChangeTimeSlotsWrapper responseWrapper = postSubmitSchedulingRequest(scheduler_request, path, uuid);
+
+ Date endTime = new Date();
+ String endTimeRequest = requestDateFormat.format(endTime);
+ System.out.println(endTimeRequest + " | Controller Scheduler - POST Submit\n");
+
+ return (new ResponseEntity<String>(responseWrapper.getResponse(), HttpStatus.OK));
+ }
+
+ protected PostSubmitVnfChangeTimeSlotsWrapper postSubmitSchedulingRequest(JSONObject request, String path, String uuid) throws Exception {
+
+ try {
+ //STARTING REST API CALL AS AN FACTORY INSTACE
+ System.out.println("<== Post Submit Scheduling Request START \n");
+
+ PostSubmitVnfChangeRestObject<String> restObjStr = new PostSubmitVnfChangeRestObject<String>();
+ String str = new String();
+
+ restObjStr.set(str);
+ restController.<String>Post(str, request, path, restObjStr);
+
+ int status = restObjStr.getStatusCode();
+ if (status >= 200 && status <= 299) {
+ restObjStr.setUUID(uuid);
+ }
+
+ PostSubmitVnfChangeTimeSlotsWrapper responseWrapper = SchedulerUtil.postSubmitNewVnfWrapResponse(restObjStr);
+
+ System.out.println("<== Post Submit Scheduling Request END : Response = " + responseWrapper.getResponse() + '\n');
+
+ return responseWrapper;
+
+ } catch (Exception e) {
+ System.out.println("<== Post Submit Scheduling Request ERROR : " + e.toString() + '\n');
+ throw e;
+ }
+ }
+}
+
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/controller/VidController.java b/vid-app-common/src/main/java/org/openecomp/vid/controller/VidController.java
index 838793a76..aac3a0b7e 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/controller/VidController.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/controller/VidController.java
@@ -67,6 +67,7 @@ public class VidController extends RestrictedBaseController {
@RequestMapping(value={"/rest/models/services"}, method = RequestMethod.GET)
public SecureServices getServices(HttpServletRequest request) throws VidServiceUnavailableException {
try {
+ LOG.info("Start API for browse ASDC was called");
SecureServices secureServices = new SecureServices();
RoleProvider roleProvider = new RoleProvider();
Map<String, String[]> requestParams = request.getParameterMap();
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/factories/MsoRequestFactory.java b/vid-app-common/src/main/java/org/openecomp/vid/factories/MsoRequestFactory.java
new file mode 100644
index 000000000..9cc9c5f66
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/factories/MsoRequestFactory.java
@@ -0,0 +1,15 @@
+package org.openecomp.vid.factories;
+
+import org.openecomp.vid.mso.rest.RequestDetails;
+
+/**
+ * Created by pickjonathan on 19/06/2017.
+ */
+public class MsoRequestFactory {
+
+ public RequestDetails createMsoRequest(String path)
+ {
+ return null;
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/model/CommandProperty.java b/vid-app-common/src/main/java/org/openecomp/vid/model/CommandProperty.java
index fe114c380..740f9d781 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/model/CommandProperty.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/model/CommandProperty.java
@@ -1,9 +1,9 @@
/*-
- * ============LICENSE_START=======================================================
- * VID
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
- * ================================================================================
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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
@@ -14,7 +14,7 @@
* 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.
+ * limitations under the License.
* ============LICENSE_END=========================================================
*/
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/model/VersionByInvariantIdsRequest.java b/vid-app-common/src/main/java/org/openecomp/vid/model/VersionByInvariantIdsRequest.java
new file mode 100644
index 000000000..7c86165b4
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/model/VersionByInvariantIdsRequest.java
@@ -0,0 +1,11 @@
+package org.openecomp.vid.model;
+
+import java.util.List;
+
+/**
+ * Created by Oren on 9/5/17.
+ */
+public class VersionByInvariantIdsRequest {
+
+ public List<String> versions;
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/model/VolumeGroup.java b/vid-app-common/src/main/java/org/openecomp/vid/model/VolumeGroup.java
index d09ef9a33..baa535171 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/model/VolumeGroup.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/model/VolumeGroup.java
@@ -161,7 +161,7 @@ public class VolumeGroup {
*
* @param u the new customization uuid
*/
- private void setCustomizationUuid(String u) {
+ public void setCustomizationUuid(String u) {
this.customizationUuid = u;
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/model/Workflow.java b/vid-app-common/src/main/java/org/openecomp/vid/model/Workflow.java
new file mode 100644
index 000000000..6032ec5aa
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/model/Workflow.java
@@ -0,0 +1,47 @@
+package org.openecomp.vid.model;
+
+
+import java.util.Collection;
+
+public class Workflow {
+ //Private members:
+ private int id;
+ private String workflowName;
+ private Collection<String> vnfNames;
+
+
+ //Constructors:
+ public Workflow() {}
+
+ public Workflow(int id, String workflowName, Collection<String> vnfNames) {
+ this.id = id;
+ this.workflowName = workflowName;
+ this.vnfNames = vnfNames;
+ }
+
+
+ //Setters and getters:
+ public int getId() {
+ return id;
+ }
+
+ public String getWorkflowName() {
+ return workflowName;
+ }
+
+ public Collection<String> getVnfNames() {
+ return this.vnfNames;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public void setWorkflowName(String workflowName) {
+ this.workflowName = workflowName;
+ }
+
+ public void setVnfName(Collection<String> vnfNames) {
+ this.vnfNames = vnfNames;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoBusinessLogic.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoBusinessLogic.java
new file mode 100644
index 000000000..cd6003ad4
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoBusinessLogic.java
@@ -0,0 +1,415 @@
+package org.openecomp.vid.mso;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.controller.MsoController;
+import org.openecomp.vid.mso.rest.*;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import static org.openecomp.vid.controller.MsoController.SVC_INSTANCE_ID;
+import static org.openecomp.vid.controller.MsoController.REQUEST_TYPE;
+import static org.openecomp.vid.controller.MsoController.VNF_INSTANCE_ID;
+
+/**
+ * Created by pickjonathan on 19/06/2017.
+ */
+public class MsoBusinessLogic {
+
+ /**
+ * The Mso REST client
+ * This should be replaced with mso client factory.
+ */
+ private MsoInterface msoClientInterface;
+
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoController.class);
+
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ public MsoBusinessLogic() {
+ msoClientInterface = MsoRestInterfaceFactory.getInstance();
+ }
+
+ // this function should get params from tosca and send them to instance at mso, then return success response.
+ public MsoResponseWrapper createSvcInstance(RequestDetails msoRequest) throws Exception {
+ String methodName = "createSvcInstance ";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_SVC_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ return msoClientInterface.createSvcInstance(msoRequest, endpoint);
+ }
+
+ public MsoResponseWrapper createVnf(RequestDetails requestDetails, String serviceInstanceId) throws Exception {
+ String methodName = "createVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String vnf_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ return msoClientInterface.createVnf(requestDetails, vnf_endpoint);
+ }
+
+ public MsoResponseWrapper createNwInstance(RequestDetails requestDetails, String serviceInstanceId) throws Exception {
+ String methodName = "createNwInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String nw_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ return msoClientInterface.createNwInstance(requestDetails, nw_endpoint);
+ }
+
+ public MsoResponseWrapper createVolumeGroupInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) throws Exception {
+ String methodName = "createVolumeGroupInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String vnf_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ vnf_endpoint = vnf_endpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
+
+ return msoClientInterface.createVolumeGroupInstance(requestDetails, vnf_endpoint);
+ }
+
+ public MsoResponseWrapper createVfModuleInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) throws Exception{
+ String methodName = "createVfModuleInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String partial_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ String vf_module_endpoint = partial_endpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
+
+ return msoClientInterface.createVfModuleInstance(requestDetails, vf_module_endpoint);
+ }
+
+ public MsoResponseWrapper deleteSvcInstance(RequestDetails requestDetails, String serviceInstanceId) throws Exception{
+ String methodName = "deleteSvcInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_SVC_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String svc_endpoint = endpoint + "/" + serviceInstanceId;
+
+ return msoClientInterface.deleteSvcInstance(requestDetails, svc_endpoint);
+ }
+
+ public MsoResponseWrapper deleteVnf(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) throws Exception{
+ String methodName = "deleteVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+ String vnf_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ vnf_endpoint = vnf_endpoint + '/' + vnfInstanceId;
+
+ return msoClientInterface.deleteVnf(requestDetails, vnf_endpoint);
+ }
+
+ public MsoResponseWrapper deleteVfModule(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) throws Exception{
+ String methodName = "deleteVfModule";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String svc_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ String delete_vf_endpoint = svc_endpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
+
+ return msoClientInterface.deleteVfModule(requestDetails, delete_vf_endpoint);
+ }
+
+ public MsoResponseWrapper deleteVolumeGroupInstance(RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId, String volumeGroupId)throws Exception{
+ String methodName = "deleteVolumeGroupInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String svc_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ String vnf_endpoint = svc_endpoint.replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
+ String delete_volume_group_endpoint = vnf_endpoint + "/" + volumeGroupId;
+
+ return msoClientInterface.deleteVolumeGroupInstance(requestDetails, delete_volume_group_endpoint);
+ }
+
+ public MsoResponseWrapper deleteNwInstance(RequestDetails requestDetails, String serviceInstanceId, String networkInstanceId) throws Exception{
+ String methodName = "deleteNwInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+
+ String svc_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ String delete_nw_endpoint = svc_endpoint + "/" + networkInstanceId;
+
+ return msoClientInterface.deleteNwInstance(requestDetails, delete_nw_endpoint);
+ }
+
+ public MsoResponseWrapper getOrchestrationRequest(String requestId)throws Exception{
+ String methodName = "getOrchestrationRequest";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+ MsoResponseWrapper w = null;
+ try {
+ String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQ);
+ String path = p + "/" + requestId;
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+
+ msoClientInterface.getOrchestrationRequest(str, "", path, restObjStr);
+
+ return MsoUtil.wrapResponse(restObjStr);
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ public MsoResponseWrapper getOrchestrationRequests(String filterString)throws Exception{
+ String methodName = "getOrchestrationRequest";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+ MsoResponseWrapper w = null;
+ try {
+ String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
+ String path = p + filterString;
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+
+ msoClientInterface.getOrchestrationRequest(str, "", path, restObjStr);
+
+ return MsoUtil.wrapResponse(restObjStr);
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ public List<Request> getOrchestrationRequestsForDashboard()throws Exception{
+ String methodName = "getOrchestrationRequestsForDashboard";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ String path = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_ORC_REQS);
+ path += "filter=modelType:EQUALS:vnf";
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+
+ MsoResponseWrapper msoResponseWrapper = msoClientInterface.getOrchestrationRequestsForDashboard(str, "", path, restObjStr);
+ List<RequestWrapper> allOrchestrationRequests = deserializeOrchestrationRequestsJson(msoResponseWrapper.getEntity());
+
+ List<Request> filteredOrchestrationRequests = new ArrayList<>();
+ for (RequestWrapper currentRequest:allOrchestrationRequests){
+ if ((currentRequest.getRequest() != null) && (currentRequest.getRequest().getRequestScope() == Request.RequestScope.VNF) && ((currentRequest.getRequest().getRequestType() ==
+ Request.RequestType.REPLACE_INSTANCE)||(currentRequest.getRequest().getRequestType() ==
+ Request.RequestType.UPDATE_INSTANCE) )) {
+ filteredOrchestrationRequests.add(currentRequest.getRequest());
+ }
+ }
+ return filteredOrchestrationRequests;
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+
+ }
+
+ private List<RequestWrapper> deserializeOrchestrationRequestsJson(String orchestrationRequestsJson) throws Exception {
+ String methodName = "deserializeOrchestrationRequestsJson";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
+ RequestList requestList = mapper.readValue(orchestrationRequestsJson , RequestList.class);
+ return requestList.getRequestList();
+ }
+
+
+ public List<Task> getManualTasksByRequestId(String originalRequestId)throws Exception{
+ String methodName = "getManualTasksByRequestId";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_MAN_TASKS);
+ String path = p + "?originalRequestId=" + originalRequestId;
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+
+ MsoResponseWrapper msoResponseWrapper = msoClientInterface.getManualTasksByRequestId(str, "", path, restObjStr);
+ return deserializeManualTasksJson(msoResponseWrapper.getEntity());
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ private List<Task> deserializeManualTasksJson(String manualTasksJson) throws Exception{
+ String methodName = "deserializeManualTasksJson";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ ObjectMapper mapper = new ObjectMapper();
+ TaskList taskList = mapper.readValue(manualTasksJson , TaskList.class);
+ return taskList.getTaskList();
+ }
+
+
+ public MsoResponseWrapper completeManualTask(RequestDetails requestDetails , String taskId)throws Exception{
+ String methodName = "completeManualTask";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+ MsoResponseWrapper w = null;
+ try {
+ String p = SystemProperties.getProperty(MsoProperties.MSO_REST_API_GET_MAN_TASKS);
+ String path = p + "/" + taskId + "/complete";
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+
+ msoClientInterface.completeManualTask(requestDetails , str, "", path, restObjStr);
+
+ return MsoUtil.wrapResponse(restObjStr);
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ public MsoResponseWrapper activateServiceInstance(RequestDetails requestDetails , String serviceInstanceId)throws Exception{
+ String methodName = "activateServiceInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+ try {
+ String path ="/" + serviceInstanceId + "/activate";
+
+ RestObject<String> restObjStr = new RestObject<>();
+ String str = "";
+ restObjStr.set(str);
+
+ msoClientInterface.activateServiceInstance(requestDetails , str, "", path, restObjStr);
+
+ return MsoUtil.wrapResponse(restObjStr);
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+
+
+
+ private String validateEndpointPath(String endpointEnvVariable) throws Exception {
+ String endpoint = SystemProperties.getProperty(endpointEnvVariable);
+ if (endpoint == null || endpoint.isEmpty()) {
+ throw new Exception(endpointEnvVariable + " env variable is not defined");
+ }
+ return endpoint;
+ }
+
+ public MsoResponseWrapper updateVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) throws Exception {
+ String methodName = "updateVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+ String vnf_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ vnf_endpoint = vnf_endpoint + '/' + vnfInstanceId;
+ return msoClientInterface.updateVnf(requestDetails, vnf_endpoint);
+ }
+
+ public MsoResponseWrapper replaceVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String serviceInstanceId, String vnfInstanceId) throws Exception {
+ String methodName = "replaceVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ String endpoint;
+ try {
+ endpoint = validateEndpointPath(MsoProperties.MSO_REST_API_VNF_CHANGE_MANAGEMENT_INSTANCE);
+ } catch (Exception exception) {
+ throw exception;
+ }
+ String vnf_endpoint = endpoint.replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
+ vnf_endpoint = vnf_endpoint.replace(VNF_INSTANCE_ID, vnfInstanceId);
+ vnf_endpoint = vnf_endpoint.replace(REQUEST_TYPE, "replace"); //No Constants file, TODO: once you create - add it.
+ return msoClientInterface.replaceVnf(requestDetails, vnf_endpoint);
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoClientFactory.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoClientFactory.java
new file mode 100644
index 000000000..fb0ead440
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoClientFactory.java
@@ -0,0 +1,37 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.mso;
+
+import org.openecomp.vid.mso.rest.MsoRestClientNew;
+
+/**
+ * A factory for creating MsoRestInterface objects.
+ */
+public class MsoClientFactory {
+
+ /**
+ * MSO client factory that creates the right client according to env.
+ * @return
+ */
+ public static MsoInterface getInstance() {
+ return new MsoRestClientNew();
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoInterface.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoInterface.java
new file mode 100644
index 000000000..cdeb1bbd2
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoInterface.java
@@ -0,0 +1,75 @@
+package org.openecomp.vid.mso;
+
+import org.openecomp.vid.mso.rest.Request;
+import org.openecomp.vid.mso.rest.RequestDetails;
+import org.openecomp.vid.mso.rest.Task;
+
+import java.util.List;
+
+/**
+ * Created by pickjonathan on 21/06/2017.
+ */
+public interface MsoInterface {
+
+ /**
+ * This function will post MSO service with information about how to instantiate the requested service
+ * @param requestDetails The details about the service as they come from the web.
+ * @return MsoResponseWrapper containing information about the service instantiation
+ * --> success : see JSON at resources folder mso_create_instance_response.
+ * --> failure : would return 200 with failure data.
+ * @throws Exception
+ */
+ MsoResponseWrapper createSvcInstance(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ /**
+ * will create a virtual network function using MSO service.
+ * @param requestDetails - information about the vnf to create
+ * @return - the response body recived from MSO
+ * @throws Exception
+ */
+ MsoResponseWrapper createVnf(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ MsoResponseWrapper createNwInstance(RequestDetails requestDetails, String endpoint) throws Exception;
+ /**
+ *
+ * @param requestDetails
+ * @param path
+ * @return
+ * @throws Exception
+ */
+ MsoResponseWrapper createVolumeGroupInstance(RequestDetails requestDetails, String path) throws Exception;
+
+ /**
+ *
+ * @param requestDetails
+ * @return
+ * @throws Exception
+ */
+ MsoResponseWrapper createVfModuleInstance(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ MsoResponseWrapper deleteSvcInstance(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ MsoResponseWrapper deleteVnf(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ MsoResponseWrapper deleteVfModule(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ MsoResponseWrapper deleteVolumeGroupInstance(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ MsoResponseWrapper deleteNwInstance(RequestDetails requestDetails, String endpoint) throws Exception;
+
+ void getOrchestrationRequest(String t, String sourceId, String endpoint, RestObject restObject) throws Exception;
+
+ MsoResponseWrapper getOrchestrationRequestsForDashboard(String t , String sourceId , String endpoint , RestObject restObject) throws Exception;
+
+ MsoResponseWrapper getManualTasksByRequestId(String t , String sourceId , String endpoint , RestObject restObject) throws Exception;
+
+ MsoResponseWrapper completeManualTask(RequestDetails requestDetails, String t, String sourceId, String endpoint, RestObject restObject) throws Exception;
+
+ MsoResponseWrapper updateVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String vnf_endpoint) throws Exception;
+
+ MsoResponseWrapper replaceVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String vnf_endpoint) throws Exception;
+
+
+ void activateServiceInstance(RequestDetails requestDetails, String t, String sourceId, String endpoint, RestObject<String> restObject) throws Exception;
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClient.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClient.java
new file mode 100644
index 000000000..0179400dc
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClient.java
@@ -0,0 +1,85 @@
+package org.openecomp.vid.mso;
+
+import org.apache.commons.io.IOUtils;
+import org.json.JSONObject;
+import org.json.JSONTokener;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
+import org.openecomp.vid.controller.VidController;
+import org.openecomp.vid.mso.rest.RequestDetails;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.core.MultivaluedHashMap;
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+/**
+ * Created by pickjonathan on 20/06/2017.
+ */
+public class MsoLocalClient implements MsoRestInterfaceIfc {
+
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoLocalClient.class);
+
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ /**
+ * The client.
+ */
+ private static Client client = null;
+
+ /**
+ * The common headers.
+ */
+ private MultivaluedHashMap<String, Object> commonHeaders;
+
+ /**
+ * Instantiates a new mso rest interface.
+ */
+ public MsoLocalClient() {
+ super();
+ }
+
+ public void initMsoClient() {
+ final String methodname = "initRestClient()";
+ }
+
+ @Override
+ public <T> void Get(T t, String sourceId, String path, RestObject<T> restObject) throws Exception {
+
+ }
+
+ @Override
+ public <T> void Delete(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception {
+
+ }
+
+ @Override
+ public <T> void Post(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception {
+ initMsoClient();
+
+ final InputStream asdcServicesFile = MsoLocalClient.class.getClassLoader().getResourceAsStream("mso_create_instance_response.json");
+
+ t = (T) IOUtils.toString(asdcServicesFile);
+ restObject.setStatusCode(200);
+ restObject.set(t);
+ }
+
+ @Override
+ public void logRequest(RequestDetails r) {
+
+ }
+
+ @Override
+ public <T> void Put(T t, ChangeManagementRequest r, String sourceID, String path, RestObject<T> restObject)
+ throws Exception {
+
+
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClientNew.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClientNew.java
new file mode 100644
index 000000000..1b15df721
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoLocalClientNew.java
@@ -0,0 +1,216 @@
+package org.openecomp.vid.mso;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.NotImplementedException;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.mso.rest.*;
+
+import java.io.InputStream;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by pickjonathan on 21/06/2017.
+ */
+public class MsoLocalClientNew implements MsoInterface {
+
+
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoLocalClient.class);
+
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+
+ @Override
+ public MsoResponseWrapper createSvcInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+
+ String methodName = "createSvcInstance ";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+ MsoResponseWrapper w = createInstance(requestDetails, "");
+
+ return w;
+ }
+
+ public MsoResponseWrapper createInstance(RequestDetails request, String path) throws Exception {
+ String methodName = "createInstance";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ RestObject<String> restObjStr = new RestObject<String>();
+
+ String str = new String();
+
+ restObjStr.set(str);
+
+ final InputStream asdcServicesFile = MsoLocalClient.class.getClassLoader().getResourceAsStream("mso_create_instance_response.json");
+
+ restObjStr.setStatusCode(200);
+ restObjStr.set(IOUtils.toString(asdcServicesFile));
+
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObjStr);
+
+ return w;
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ @Override
+ public MsoResponseWrapper createVnf(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper createNwInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper createVolumeGroupInstance(RequestDetails requestDetails, String path) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper createVfModuleInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper deleteSvcInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper deleteVnf(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper deleteVfModule(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper deleteVolumeGroupInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public MsoResponseWrapper deleteNwInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ return null;
+ }
+
+ @Override
+ public void getOrchestrationRequest(String t, String sourceId, String endpoint, RestObject restObject) throws Exception { }
+
+ @Override
+ public MsoResponseWrapper getOrchestrationRequestsForDashboard(String t, String sourceId, String endpoint, RestObject restObject) throws Exception {
+ String methodName = "getOrchestrationRequestsForDashboard";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+
+ final InputStream asdcServicesFile = MsoLocalClient.class.getClassLoader().getResourceAsStream("mso_get_orchestration_requests.json");
+
+ restObject.setStatusCode(200);
+ restObject.set(IOUtils.toString(asdcServicesFile));
+
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+
+ return w;
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ public void activateServiceInstance(RequestDetails requestDetails, String t, String sourceId, String endpoint, RestObject<String> restObject) throws Exception{
+ String methodName = "activateServiceInstance";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+
+ final InputStream asdcServicesFile = MsoLocalClient.class.getClassLoader().getResourceAsStream("mso_activate_service_instance.json");
+
+ restObject.setStatusCode(200);
+ restObject.set(IOUtils.toString(asdcServicesFile));
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+
+ @Override
+ public MsoResponseWrapper getManualTasksByRequestId(String t, String sourceId, String endpoint, RestObject restObject) throws Exception {
+ String methodName = "getManualTasksByRequestId";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+
+ final InputStream asdcServicesFile = MsoLocalClient.class.getClassLoader().getResourceAsStream("mso_get_manual_task_by_request_id.json");
+
+ restObject.setStatusCode(200);
+ restObject.set(IOUtils.toString(asdcServicesFile));
+
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+
+ return w;
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ @Override
+ public MsoResponseWrapper completeManualTask(RequestDetails requestDetails, String t, String sourceId, String endpoint, RestObject restObject) throws Exception {
+ String methodName = "getManualTasksByRequestId";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+
+ final InputStream asdcServicesFile = MsoLocalClient.class.getClassLoader().getResourceAsStream("mso_complete_manual_task.json");
+
+ restObject.setStatusCode(200);
+ restObject.set(IOUtils.toString(asdcServicesFile));
+
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+
+ return w;
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ @Override
+ public MsoResponseWrapper replaceVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String vnf_endpoint) throws Exception {
+ throw new NotImplementedException("Function was not implemented at this point.");
+ }
+
+
+
+ @Override
+ public MsoResponseWrapper updateVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails,
+ String vnf_endpoint) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoProperties.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoProperties.java
index 272a2a2b8..0eed0e1d1 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoProperties.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoProperties.java
@@ -24,7 +24,6 @@ import org.openecomp.portalsdk.core.util.SystemProperties;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.Date;
import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
/**
@@ -35,10 +34,10 @@ public class MsoProperties extends SystemProperties {
/** The Constant MSO_SERVER_URL. */
//VID Properties related to MSO
public static final String MSO_SERVER_URL = "mso.server.url";
-
+
/** The Constant MSO_DME2_SERVER_URL. */
public static final String MSO_DME2_SERVER_URL = "mso.dme2.server.url";
-
+
/** The Constant MSO_DME2_CLIENT_TIMEOUT. */
public static final String MSO_DME2_CLIENT_TIMEOUT = "mso.dme2.client.timeout";
@@ -51,7 +50,7 @@ public class MsoProperties extends SystemProperties {
/** The Constant MSO_POLLING_INTERVAL_MSECS. */
// number of msecs to wait between polling requests
public static final String MSO_POLLING_INTERVAL_MSECS = "mso.polling.interval.msecs";
-
+
/** The Constant MSO_POLLING_INTERVAL_MSECS_DEFAULT. */
public static final String MSO_POLLING_INTERVAL_MSECS_DEFAULT = "60000";
@@ -68,14 +67,17 @@ public class MsoProperties extends SystemProperties {
public static final String MSO_USER_NAME = "mso.user.name"; //m03346
/** The Constant MSO_PASSWORD. */
- public static final String MSO_PASSWORD = "mso.password.x";
+ public static final String MSO_PASSWORD = "mso.password.x";
/** The Constant MSO_REST_API_SVC_INSTANCE. */
- public static final String MSO_REST_API_SVC_INSTANCE = "mso.restapi.svc.instance"; // /serviceInstances/v2
+ public static final String MSO_REST_API_SVC_INSTANCE = "mso.restapi.svc.instance"; // /serviceInstances/v2
/** The Constant MSO_REST_API_VNF_INSTANCE. */
public static final String MSO_REST_API_VNF_INSTANCE = "mso.restapi.vnf.instance"; // /serviceInstances/v2/{service_instance_id}/vnfs
+ /** The Constant MSO_REST_API_VNF_CHANGE_MANAGEMENT_INSTANCE. */
+ public static final String MSO_REST_API_VNF_CHANGE_MANAGEMENT_INSTANCE = "mso.restapi.vnf.changemanagement.instance"; // /serviceInstances/v2/{service_instance_id}/vnfs/{request_type}
+
/** The Constant MSO_REST_API_NETWORK_INSTANCE. */
public static final String MSO_REST_API_NETWORK_INSTANCE = "mso.restapi.network.instance"; // /serviceInstances/v2/{serviceInstanceId}/networks
@@ -84,10 +86,13 @@ public class MsoProperties extends SystemProperties {
/** The Constant MSO_REST_API_GET_ORC_REQS. */
public static final String MSO_REST_API_GET_ORC_REQS = "mso.restapi.get.orc.reqs";
-
+
+ /** The Constant MSO_REST_API_GET_MAN_TASK. */
+ public static final String MSO_REST_API_GET_MAN_TASKS = "mso.restapi.get.man.tasks";
+
/** The Constant MSO_REST_API_VF_MODULE_INSTANCE. */
public static final String MSO_REST_API_VF_MODULE_INSTANCE = "mso.restapi.vf.module.instance";
-
+
/** The Constant MSO_REST_API_VOLUME_GROUP_INSTANCE. */
public static final String MSO_REST_API_VOLUME_GROUP_INSTANCE = "mso.restapi.volume.group.instance"; //serviceInstances/v2/{serviceInstanceId}/volumeGroups
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterface.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterface.java
index f964b8353..5b331e908 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterface.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterface.java
@@ -37,6 +37,7 @@ import org.openecomp.portalsdk.core.util.SystemProperties;
import org.apache.commons.codec.binary.Base64;
import org.eclipse.jetty.util.security.Password;
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
import org.openecomp.vid.client.HttpBasicClient;
import org.openecomp.vid.client.HttpsBasicClient;
import org.openecomp.vid.mso.rest.RequestDetails;
@@ -57,7 +58,7 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
/** The common headers. */
private MultivaluedHashMap<String, Object> commonHeaders;
-
+
/**
* Instantiates a new mso rest interface.
*/
@@ -68,7 +69,7 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
/* (non-Javadoc)
* @see org.openecomp.vid.mso.MsoRestInterfaceIfc#initRestClient()
*/
- public void initRestClient()
+ public void initMsoClient()
{
final String methodname = "initRestClient()";
@@ -131,7 +132,7 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
- initRestClient();
+ initMsoClient();
final Response cres = client.target(url)
.request()
@@ -170,7 +171,7 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
logRequest (r);
try {
- initRestClient();
+ initMsoClient();
url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + " methodName sending request to: " + url);
@@ -232,8 +233,64 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
logRequest (r);
try {
+
+ initMsoClient();
+
+ url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
+ // Change the content length
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.header("content-length", 201)
+ //.header("X-FromAppId", sourceID)
+ .post(Entity.entity(r, MediaType.APPLICATION_JSON));
- initRestClient();
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " No response entity, this is probably ok, e="
+ + e.getMessage());
+ }
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if ( status >= 200 && status <= 299 ) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+
+ } else {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with status="+status+", url="+url);
+ }
+
+ } catch (Exception e)
+ {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ throw e;
+
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.openecomp.vid.mso.MsoRestInterfaceIfc#Put(java.lang.Object, org.openecomp.vid.mso.rest.RequestDetails, java.lang.String, java.lang.String, org.openecomp.vid.mso.RestObject)
+ */
+ @SuppressWarnings("unchecked")
+ public <T> void Put(T t, ChangeManagementRequest r, String sourceID, String path, RestObject<T> restObject) throws Exception {
+
+ String methodName = "Put";
+ String url="";
+
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+// logRequest (r);
+ try {
+
+ initMsoClient();
url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
@@ -244,7 +301,7 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
.headers(commonHeaders)
//.header("content-length", 201)
//.header("X-FromAppId", sourceID)
- .post(Entity.entity(r, MediaType.APPLICATION_JSON));
+ .put(Entity.entity(r, MediaType.APPLICATION_JSON));
try {
t = (T) cres.readEntity(t.getClass());
@@ -287,7 +344,9 @@ public class MsoRestInterface extends MsoRestInt implements MsoRestInterfaceIfc
public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException
{
return clazz.newInstance();
- }
+ }
+
+
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceFactory.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceFactory.java
index 8bb3093c1..ab12c7b14 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceFactory.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceFactory.java
@@ -21,28 +21,24 @@
package org.openecomp.vid.mso;
import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.mso.rest.MsoRestClientNew;
/**
* A factory for creating MsoRestInterface objects.
*/
public class MsoRestInterfaceFactory {
-
- /**
- * Gets the single instance of MsoRestInterfaceFactory.
- *
- * @return single instance of MsoRestInterfaceFactory
- */
- public static MsoRestInterfaceIfc getInstance () {
- MsoRestInterfaceIfc obj = null;
-
-// String mso_dme2_enabled = SystemProperties.getProperty(MsoProperties.MSO_DME2_ENABLED);
-// if ( (mso_dme2_enabled != null) && (mso_dme2_enabled.equalsIgnoreCase("true") ) ) {
-// obj = new MsoDme2RestInterface();
-// }
-// else {
- obj = new MsoRestInterface();
-// }
- return ( obj );
- }
+ /**
+ * Gets the single instance of MsoRestInterfaceFactory.
+ *
+ * @return single instance of MsoRestInterfaceFactory
+ */
+ public static MsoInterface getInstance() {
+ String msoPropertyName = "mso.client.type";
+ if (SystemProperties.containsProperty(msoPropertyName) &&
+ SystemProperties.getProperty(msoPropertyName).equals("LOCAL")) {
+ return new MsoLocalClientNew();
+ } else
+ return new MsoRestClientNew();
+ }
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceIfc.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceIfc.java
index 1a6dbcccb..4ff13eddd 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceIfc.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/MsoRestInterfaceIfc.java
@@ -20,6 +20,7 @@
package org.openecomp.vid.mso;
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
import org.openecomp.vid.mso.rest.RequestDetails;
/**
@@ -30,7 +31,7 @@ public interface MsoRestInterfaceIfc {
/**
* Inits the rest client.
*/
- public void initRestClient();
+ public void initMsoClient();
/**
* Gets the.
@@ -70,6 +71,18 @@ public interface MsoRestInterfaceIfc {
*/
public <T> void Post(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception;
+ /**
+ * Put.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param r the r
+ * @param sourceID the source ID
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Put(T t, ChangeManagementRequest r, String sourceID, String path, RestObject<T> restObject) throws Exception ;
/***
* Log request.
*
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/RestMsoImplementation.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/RestMsoImplementation.java
new file mode 100644
index 000000000..ba0fdfaa8
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/RestMsoImplementation.java
@@ -0,0 +1,326 @@
+package org.openecomp.vid.mso;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.commons.codec.binary.Base64;
+import org.eclipse.jetty.util.security.Password;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.changeManagement.MsoRequestDetails;
+import org.openecomp.vid.client.HttpBasicClient;
+import org.openecomp.vid.client.HttpsBasicClient;
+import org.openecomp.vid.mso.rest.RequestDetails;
+import org.openecomp.vid.mso.rest.RestInterface;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.Response;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+
+/**
+ * Created by pickjonathan on 26/06/2017.
+ */
+public class RestMsoImplementation implements RestInterface {
+
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(RestMsoImplementation.class);
+
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ /** The client. */
+ private static Client client = null;
+
+ /** The common headers. */
+ private MultivaluedHashMap<String, Object> commonHeaders;
+ /**
+ * Instantiates a new mso rest interface.
+ */
+
+ @Override
+ public void initMsoClient()
+ {
+ final String methodname = "initRestClient()";
+
+ final String username = SystemProperties.getProperty(MsoProperties.MSO_USER_NAME);
+ final String password = SystemProperties.getProperty(MsoProperties.MSO_PASSWORD);
+ final String mso_url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL);
+ final String decrypted_password = Password.deobfuscate(password);
+
+ String authString = username + ":" + decrypted_password;
+
+ byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
+ String authStringEnc = new String(authEncBytes);
+
+ commonHeaders = new MultivaluedHashMap<String, Object>();
+ commonHeaders.put("Authorization", Collections.singletonList((Object) ("Basic " + authStringEnc)));
+
+ boolean use_ssl = true;
+ if ( (mso_url != null) && ( !(mso_url.isEmpty()) ) ) {
+ if ( mso_url.startsWith("https")) {
+ use_ssl = true;
+ }
+ else {
+ use_ssl = false;
+ }
+ }
+ if (client == null) {
+
+ try {
+ if ( use_ssl ) {
+ //logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + methodname + " getting HttpsBasicClient with username=" + username
+ // + " password=" + password);
+ client = HttpsBasicClient.getClient();
+ }
+ else {
+ //logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + methodname + " getting HttpsBasicClient with username=" + username
+ // + " password=" + password);
+ client = HttpBasicClient.getClient();
+ }
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + methodname + " Unable to get the SSL client");
+ }
+ }
+ }
+
+ public <T> void Get (T t, String sourceId, String path, RestObject<T> restObject ) throws Exception {
+ String methodName = "Get";
+
+ logger.debug(EELFLoggerDelegate.debugLogger, methodName + " start");
+
+ String url="";
+ restObject.set(t);
+
+ url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
+
+ initMsoClient();
+
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ .get();
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if (status == 200 || status == 202) {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + methodName + " REST api was successfull!");
+
+ } else {
+ throw new Exception(methodName + " with status="+ status + ", url= " + url );
+ }
+
+ logger.debug(EELFLoggerDelegate.debugLogger,methodName + " received status=" + status );
+
+ return;
+ }
+
+ @Override
+ public <T> void Delete(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) {
+
+ String methodName = "Delete";
+ String url="";
+ Response cres = null;
+
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " start");
+ logRequest (r);
+
+ try {
+ initMsoClient();
+
+ url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + " methodName sending request to: " + url);
+
+ cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.entity(r)
+ .build("DELETE", Entity.entity(r, MediaType.APPLICATION_JSON)).invoke();
+ // .method("DELETE", Entity.entity(r, MediaType.APPLICATION_JSON));
+ //.delete(Entity.entity(r, MediaType.APPLICATION_JSON));
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if (status == 404) { // resource not found
+ String msg = "Resource does not exist...: " + cres.getStatus();
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + msg);
+ } else if (status == 200 || status == 204){
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + "Resource " + url + " deleted");
+ } else if (status == 202) {
+ String msg = "Delete in progress: " + status;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + msg);
+ }
+ else {
+ String msg = "Deleting Resource failed: " + status;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + msg);
+ }
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " No response entity, this is probably ok, e="
+ + e.getMessage());
+ }
+
+ }
+ catch (Exception e)
+ {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ throw e;
+
+ }
+ }
+
+ @Override
+ public <T> void Post(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception {
+ String methodName = "Post";
+ String url="";
+
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ logRequest (r);
+ try {
+
+ initMsoClient();
+
+ url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
+ // Change the content length
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.header("content-length", 201)
+ //.header("X-FromAppId", sourceID)
+ .post(Entity.entity(r, MediaType.APPLICATION_JSON));
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " No response entity, this is probably ok, e="
+ + e.getMessage());
+ }
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if ( status >= 200 && status <= 299 ) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+
+ } else {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with status="+status+", url="+url);
+ }
+
+ } catch (Exception e)
+ {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ throw e;
+
+ }
+ }
+
+ @Override
+ public void logRequest(RequestDetails r) {
+ String methodName = "logRequest";
+ ObjectMapper mapper = new ObjectMapper();
+ String r_json_str = "";
+ if ( r != null ) {
+ r_json_str = r.toString();
+ try {
+ r_json_str = mapper.writeValueAsString(r);
+ }
+ catch ( com.fasterxml.jackson.core.JsonProcessingException j ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Unable to parse request as json");
+ }
+ }
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Request=(" + r_json_str + ")");
+ }
+
+ @Override
+ public void logRequest(org.openecomp.vid.changeManagement.RequestDetails r) {
+ String methodName = "logRequest";
+ ObjectMapper mapper = new ObjectMapper();
+ String r_json_str = "";
+ if ( r != null ) {
+ r_json_str = r.toString();
+ try {
+ r_json_str = mapper.writeValueAsString(r);
+ }
+ catch ( com.fasterxml.jackson.core.JsonProcessingException j ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Unable to parse request as json");
+ }
+ }
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Request=(" + r_json_str + ")");
+ }
+
+ @Override
+ public <T> void Put(T t, org.openecomp.vid.changeManagement.RequestDetailsWrapper r, String sourceID, String path, RestObject<T> restObject) throws Exception {
+
+ String methodName = "Put";
+ String url="";
+
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+// logRequest (r);
+ try {
+
+ initMsoClient();
+
+ url = SystemProperties.getProperty(MsoProperties.MSO_SERVER_URL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
+ // Change the content length
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.header("content-length", 201)
+ //.header("X-FromAppId", sourceID)
+ .put(Entity.entity(r, MediaType.APPLICATION_JSON));
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " No response entity, this is probably ok, e="
+ + e.getMessage());
+ }
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if ( status >= 200 && status <= 299 ) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " REST api POST was successful!");
+
+ } else {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with status="+status+", url="+url);
+ }
+
+ } catch (Exception e)
+ {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ throw e;
+
+ }
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoBusinessLogicNew.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoBusinessLogicNew.java
new file mode 100644
index 000000000..1afb2df21
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoBusinessLogicNew.java
@@ -0,0 +1,67 @@
+package org.openecomp.vid.mso.rest;
+
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.mso.MsoClientFactory;
+import org.openecomp.vid.mso.MsoInterface;
+import org.openecomp.vid.mso.MsoResponseWrapper;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by pickjonathan on 21/06/2017.
+ * This class was created only for testing the new logic.
+ * It is not used by any of the controllers binded to the ui.
+ * This can be deleted in the future in order to keep a cleaner project.
+ * If deleting please dont forget to delete the controllers, factory and all involved in the assert test.
+ */
+public class MsoBusinessLogicNew {
+
+ /**
+ * \
+ * The MSO Client
+ */
+ private MsoInterface msoClient;
+
+ private MsoInterface msoRestTempClient;
+
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoBusinessLogicNew.class);
+
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ public MsoBusinessLogicNew() {
+ msoClient = MsoClientFactory.getInstance();
+ msoRestTempClient = new MsoRestClientNew();
+ }
+
+ public MsoResponseWrapper createSvcInstance(RequestDetails msoRequest) throws Exception {
+ String methodName = "createSvcInstance ";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+// String endpoint = SystemProperties.getProperty(MsoProperties.MSO_REST_API_SVC_INSTANCE);
+//
+// MsoResponseWrapper w = createInstance(msoRequest, p);
+
+ MsoResponseWrapper w = msoClient.createSvcInstance(msoRequest, "");
+
+ return w;
+ }
+
+
+ public MsoResponseWrapper createSvcInstanceRest(RequestDetails msoRequest) throws Exception {
+ String methodName = "createSvcInstance ";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+
+ MsoResponseWrapper w = msoRestTempClient.createSvcInstance(msoRequest, "");
+
+ return w;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoRestClientNew.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoRestClientNew.java
new file mode 100644
index 000000000..1beeafb13
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/MsoRestClientNew.java
@@ -0,0 +1,333 @@
+package org.openecomp.vid.mso.rest;
+
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.changeManagement.MsoRequestDetails;
+import org.openecomp.vid.changeManagement.RequestDetailsWrapper;
+import org.openecomp.vid.mso.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+/**
+ * Created by pickjonathan on 21/06/2017.
+ */
+public class MsoRestClientNew extends RestMsoImplementation implements MsoInterface {
+
+ /**
+ * The logger.
+ */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(MsoRestClientNew.class);
+
+ /**
+ * The Constant dateFormat.
+ */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ private final String ORIGINAL_REQUEST_ID = "originalRequestId";
+
+
+ @Override
+ public MsoResponseWrapper createSvcInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "createSvcInstance ";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return createInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper createVnf(RequestDetails requestDetails, String endpoint) throws Exception {
+
+ String methodName = "createVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return createInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper createNwInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+
+ String methodName = "createNwInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return createInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper createVolumeGroupInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "createVolumeGroupInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return createInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper createVfModuleInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "createVfModuleInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return createInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper deleteSvcInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "deleteSvcInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return deleteInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper deleteVnf(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "deleteVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return deleteInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper deleteVfModule(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "deleteVfModule";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return deleteInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper deleteVolumeGroupInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "deleteVolumeGroupInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return deleteInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public MsoResponseWrapper deleteNwInstance(RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "deleteNwInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return deleteInstance(requestDetails, endpoint);
+ }
+
+ @Override
+ public void getOrchestrationRequest(String t, String sourceId, String endpoint, RestObject restObject) throws Exception {
+ Get(t, sourceId, endpoint, restObject);
+ }
+
+ public void getManualTasks(String t, String sourceId, String endpoint, RestObject restObject) throws Exception {
+ Get(t, sourceId, endpoint, restObject);
+ }
+
+
+ public MsoResponseWrapper createInstance(RequestDetails request, String path) throws Exception {
+ String methodName = "createInstance";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ RestObject<String> restObjStr = new RestObject<String>();
+
+ String str = new String();
+
+ restObjStr.set(str);
+
+ Post(str, request, "", path, restObjStr);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObjStr);
+
+ return w;
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+
+ /**
+ * Delete instance.
+ *
+ * @param request the request
+ * @param path the path
+ * @return the mso response wrapper
+ * @throws Exception the exception
+ */
+ public MsoResponseWrapper deleteInstance(RequestDetails request, String path) throws Exception {
+ String methodName = "deleteInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " calling Delete, path =[" + path + "]");
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+ Delete(str, request, "", path, restObjStr);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObjStr);
+
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+ return w;
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+
+ }
+
+ public MsoResponseWrapper getOrchestrationRequestsForDashboard(String t, String sourceId, String endpoint, RestObject restObject) throws Exception{
+ String methodName = "getOrchestrationRequestsForDashboard";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ getOrchestrationRequest(t, sourceId, endpoint, restObject);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+
+ return w;
+
+ } catch (Exception e){
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ public MsoResponseWrapper getManualTasksByRequestId(String t , String sourceId , String endpoint , RestObject restObject) throws Exception{
+ String methodName = "getManualTasksByRequestId";
+ logger.debug(dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ getManualTasks(t , sourceId , endpoint , restObject);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+
+ return MsoUtil.wrapResponse(restObject);
+
+ } catch (Exception e){
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+
+
+ @Override
+ public MsoResponseWrapper completeManualTask(RequestDetails requestDetails, String t, String sourceId, String endpoint, RestObject restObject) throws Exception {
+ String methodName = "completeManualTask";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " calling Complete ");
+ try {
+
+ Post(t, requestDetails , sourceId, endpoint, restObject);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+ return w;
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+ @Override
+ public MsoResponseWrapper replaceVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "replaceVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ return replaceInstance(requestDetails, endpoint);
+ }
+
+ public MsoResponseWrapper replaceInstance(org.openecomp.vid.changeManagement.RequestDetails request, String path) throws Exception {
+ String methodName = "replaceInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " calling Replace VNF, path =[" + path + "]");
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+ RequestDetailsWrapper requestDetailsWrapper = new RequestDetailsWrapper();
+ requestDetailsWrapper.requestDetails = new MsoRequestDetails(request);
+
+ Post(str, request, "", path, restObjStr);
+ MsoResponseWrapper msoResponseWrapperObject = MsoUtil.wrapResponse(restObjStr);
+ int status = msoResponseWrapperObject.getStatus();
+ if (status == 202){
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName +
+ ",post succeeded, msoResponseWrapperObject response:" + msoResponseWrapperObject.getResponse());
+ }
+ else {
+ logger.error(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName +
+ ": post failed, msoResponseWrapperObject status" + status + ", response:" + msoResponseWrapperObject.getResponse());
+
+ // TODO
+ }
+ return msoResponseWrapperObject;
+
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+
+ }
+
+ @Override
+ public MsoResponseWrapper updateVnf(org.openecomp.vid.changeManagement.RequestDetails requestDetails, String endpoint) throws Exception {
+ String methodName = "updateVnf";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+ RequestDetailsWrapper wrapper = new RequestDetailsWrapper();
+ wrapper.requestDetails = new MsoRequestDetails(requestDetails);;
+ return updateInstance(requestDetails, endpoint);
+ }
+
+ public MsoResponseWrapper updateInstance(org.openecomp.vid.changeManagement.RequestDetails request, String path) throws Exception {
+ String methodName = "updateInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start");
+
+ try {
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " calling Delete, path =[" + path + "]");
+
+ RestObject<String> restObjStr = new RestObject<String>();
+ String str = new String();
+ restObjStr.set(str);
+ RequestDetailsWrapper requestDetailsWrapper = new RequestDetailsWrapper();
+ requestDetailsWrapper.requestDetails = new MsoRequestDetails(request);
+
+
+
+ Put(str, requestDetailsWrapper, "", path, restObjStr);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObjStr);
+
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w=" + w.getResponse());
+ return w;
+
+ } catch (Exception e) {
+ logger.info(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+
+ }
+
+ public void activateServiceInstance(RequestDetails requestDetails, String t, String sourceId, String endpoint, RestObject<String> restObject) throws Exception{
+ String methodName = "activateServiceInstance";
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " start ");
+ try {
+
+ Post(t, requestDetails , sourceId, endpoint, restObject);
+ MsoResponseWrapper w = MsoUtil.wrapResponse(restObject);
+
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " w =" + w.getResponse());
+
+ } catch (Exception e) {
+ logger.error(EELFLoggerDelegate.errorLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + "." + methodName + e.toString());
+ throw e;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RelatedModel.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RelatedModel.java
index dc67a9456..427d71dd1 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RelatedModel.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RelatedModel.java
@@ -46,6 +46,10 @@ public class RelatedModel extends org.openecomp.vid.domain.mso.RelatedModel {
/** (Required). */
@JsonProperty("modelInfo")
private org.openecomp.vid.domain.mso.ModelInfo modelInfo;
+
+// /** The related model object instance list. */
+// @JsonProperty("instanceId")
+// private org.openecomp.vid.domain.mso.InstanceIds instanceId;
/** The additional properties. */
@JsonIgnore
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestDetails.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestDetails.java
index 6e7c5af32..0cf697e0b 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestDetails.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestDetails.java
@@ -65,7 +65,7 @@ public class RequestDetails extends org.openecomp.vid.domain.mso.RequestDetails
/** The related model list. */
@JsonProperty("relatedModelList")
- private List<RelatedModel> relatedModelList;
+ private List<RelatedModel> relatedInstanceList;
/** The request info. */
@JsonProperty("requestInfo")
@@ -122,25 +122,24 @@ public class RequestDetails extends org.openecomp.vid.domain.mso.RequestDetails
public void setModelInfo(ModelInfo modelInfo) {
this.modelInfo = modelInfo;
}
-
/**
- * Gets the related model list.
+ * Gets the related instance list.
*
- * @return The relatedModelList
+ * @return The relatedInstanceList
*/
- @JsonProperty("relatedModelList")
- public List<RelatedModel> getRelatedModelList() {
- return relatedModelList;
+ @JsonProperty("relatedInstanceList")
+ public List<RelatedModel> getRelatedInstanceList() {
+ return relatedInstanceList;
}
/**
* Sets the related model list.
*
- * @param relatedModelList The relatedModelList
+ * @param relatedInstanceList The relatedInstanceList
*/
- @JsonProperty("relatedModelList")
- public void setRelatedModelList( List<RelatedModel> relatedModelList) {
- this.relatedModelList = relatedModelList;
+ @JsonProperty("relatedInstanceList")
+ public void setRelatedInstanceList( List<RelatedModel> relatedInstanceList) {
+ this.relatedInstanceList = relatedInstanceList;
}
/**
@@ -212,7 +211,7 @@ public class RequestDetails extends org.openecomp.vid.domain.mso.RequestDetails
*/
@Override
public int hashCode() {
- return new HashCodeBuilder().append(cloudConfiguration).append(modelInfo).append(relatedModelList).append(requestInfo).append(getRequestParameters()).append(subscriberInfo).append(additionalProperties).toHashCode();
+ return new HashCodeBuilder().append(cloudConfiguration).append(modelInfo).append(relatedInstanceList).append(requestInfo).append(getRequestParameters()).append(subscriberInfo).append(additionalProperties).toHashCode();
}
/* (non-Javadoc)
@@ -227,7 +226,7 @@ public class RequestDetails extends org.openecomp.vid.domain.mso.RequestDetails
return false;
}
RequestDetails rhs = ((RequestDetails) other);
- return new EqualsBuilder().append(cloudConfiguration, rhs.cloudConfiguration).append(modelInfo, rhs.modelInfo).append(relatedModelList, rhs.relatedModelList).append(requestInfo, rhs.requestInfo).append(getRequestParameters(), rhs.getRequestParameters()).append(subscriberInfo, rhs.subscriberInfo).append(additionalProperties, rhs.additionalProperties).isEquals();
+ return new EqualsBuilder().append(cloudConfiguration, rhs.cloudConfiguration).append(modelInfo, rhs.modelInfo).append(relatedInstanceList, rhs.relatedInstanceList).append(requestInfo, rhs.requestInfo).append(getRequestParameters(), rhs.getRequestParameters()).append(subscriberInfo, rhs.subscriberInfo).append(additionalProperties, rhs.additionalProperties).isEquals();
}
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestList.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestList.java
index 7c366ac82..8a57c74b7 100755
--- a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestList.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestList.java
@@ -58,7 +58,7 @@ import java.util.List;
public class RequestList {
/** The request list. */
- private List<Request> requestList;
+ private List<RequestWrapper> requestList;
/** The additional properties. */
@JsonIgnore
@@ -69,7 +69,7 @@ public class RequestList {
*
* @return The RelatedModel List
*/
- public List<Request> getRequestList() {
+ public List<RequestWrapper> getRequestList() {
return requestList;
}
@@ -78,7 +78,7 @@ public class RequestList {
*
* @param l the new request list
*/
- public void setRequestList(List<Request> l) {
+ public void setRequestList(List<RequestWrapper> l) {
this.requestList = l;
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestWrapper.java
new file mode 100644
index 000000000..b0e9fa125
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RequestWrapper.java
@@ -0,0 +1,35 @@
+package org.openecomp.vid.mso.rest;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * request wrapper structure.
+ */
+public class RequestWrapper {
+
+
+ /** The request. */
+ private Request request;
+
+
+ /**
+ * Gets the request.
+ *
+ * @return The requestDetails
+ */
+ @JsonProperty("request")
+ public Request getRequest() {
+ return request;
+ }
+
+ /**
+ * Sets the request.
+ *
+ * @param request The request
+ */
+ @JsonProperty
+ public void setRequest(Request request) {
+ this.request = request;
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Response.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Response.java
new file mode 100644
index 000000000..ee3a8bfef
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Response.java
@@ -0,0 +1,54 @@
+package org.openecomp.vid.mso.rest;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Response {
+
+ /** The status. */
+ private int status;
+
+ /** The entity. */
+ private RequestList entity;
+
+ /**
+ * Gets the status.
+ *
+ * @return The status
+ */
+ @JsonProperty("status")
+ public int getStatus() {
+ return status;
+ }
+
+ /**
+ * Sets the status.
+ *
+ * @param status The status
+ */
+ @JsonProperty("status")
+ public void setStatus(int status) {
+ this.status = status;
+ }
+
+ /**
+ * Gets the entity.
+ *
+ * @return The entity
+ */
+ @JsonProperty("entity")
+ public RequestList getEntity() {
+ return entity;
+ }
+
+ /**
+ * Sets the entity.
+ *
+ * @param entity The entity
+ */
+ @JsonProperty("entity")
+ public void setEntity(RequestList entity) {
+ this.entity = entity;
+ }
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RestInterface.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RestInterface.java
new file mode 100644
index 000000000..1e2733587
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/RestInterface.java
@@ -0,0 +1,81 @@
+package org.openecomp.vid.mso.rest;
+
+import org.openecomp.vid.mso.RestObject;
+
+/**
+ * Created by pickjonathan on 26/06/2017.
+ */
+public interface RestInterface {
+
+ /**
+ * Inits the rest client.
+ */
+ public void initMsoClient();
+
+ /**
+ * Gets the.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param sourceId the source id
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Get (T t, String sourceId, String path, RestObject<T> restObject ) throws Exception;
+
+ /**
+ * Delete.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param r the r
+ * @param sourceID the source ID
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Delete(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception;
+
+ /**
+ * Post.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param r the r
+ * @param sourceID the source ID
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Post(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception;
+
+ /**
+ * Put.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param r the r
+ * @param sourceID the source ID
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Put(T t, org.openecomp.vid.changeManagement.RequestDetailsWrapper r, String sourceID, String path, RestObject<T> restObject) throws Exception;
+
+
+ /***
+ * Log request.
+ *
+ * @param r the r
+ */
+ public void logRequest ( RequestDetails r );
+ /***
+ * Log request.
+ *
+ * @param r the r
+ */
+ public void logRequest(org.openecomp.vid.changeManagement.RequestDetails r);
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Task.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Task.java
new file mode 100644
index 000000000..8d72890ff
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/Task.java
@@ -0,0 +1,119 @@
+package org.openecomp.vid.mso.rest;
+
+import java.util.List;
+
+public class Task {
+
+ private String taskId;
+ private String type;
+ private String nfRole;
+ private String subscriptionServiceType;
+ private String originalRequestId;
+ private String originalRequestorId;
+ private String errorSource;
+ private String errorCode;
+ private String errorMessage;
+ private String buildingBlockName;
+ private String buildingBlockStep;
+ private List<String> validResponses;
+
+
+ public String getTaskId() {
+ return taskId;
+ }
+
+ public void setTaskId(String taskId) {
+ this.taskId = taskId;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getNfRole() {
+ return nfRole;
+ }
+
+ public void setNfRole(String nfRole) {
+ this.nfRole = nfRole;
+ }
+
+ public String getSubscriptionServiceType() {
+ return subscriptionServiceType;
+ }
+
+ public void setSubscriptionServiceType(String subscriptionServiceType) {
+ this.subscriptionServiceType = subscriptionServiceType;
+ }
+
+ public String getOriginalRequestId() {
+ return originalRequestId;
+ }
+
+ public void setOriginalRequestId(String originalRequestId) {
+ this.originalRequestId = originalRequestId;
+ }
+
+ public String getOriginalRequestorId() {
+ return originalRequestorId;
+ }
+
+ public void setOriginalRequestorId(String originalRequestorId) {
+ this.originalRequestorId = originalRequestorId;
+ }
+
+ public String getErrorSource() {
+ return errorSource;
+ }
+
+ public void setErrorSource(String errorSource) {
+ this.errorSource = errorSource;
+ }
+
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ public void setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public void setErrorMessage(String errorMessage) {
+ this.errorMessage = errorMessage;
+ }
+
+ public String getBuildingBlockName() {
+ return buildingBlockName;
+ }
+
+ public void setBuildingBlockName(String buildingBlockName) {
+ this.buildingBlockName = buildingBlockName;
+ }
+
+ public String getBuildingBlockStep() {
+ return buildingBlockStep;
+ }
+
+ public void setBuildingBlockStep(String buildingBlockStep) {
+ this.buildingBlockStep = buildingBlockStep;
+ }
+
+ public List<String> getValidResponses() {
+ return validResponses;
+ }
+
+ public void setValidResponses(List<String> validResponses) {
+ this.validResponses = validResponses;
+ }
+
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/TaskList.java b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/TaskList.java
new file mode 100644
index 000000000..7232364a3
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/mso/rest/TaskList.java
@@ -0,0 +1,16 @@
+package org.openecomp.vid.mso.rest;
+
+import java.util.List;
+
+public class TaskList {
+
+ public List<Task> getTaskList() {
+ return taskList;
+ }
+
+ public void setTaskList(List<Task> taskList) {
+ this.taskList = taskList;
+ }
+
+ private List<Task> taskList;
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyProperties.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyProperties.java
new file mode 100644
index 000000000..d273aa6a7
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyProperties.java
@@ -0,0 +1,26 @@
+package org.openecomp.vid.policy;
+
+import org.openecomp.portalsdk.core.util.SystemProperties;
+
+
+public class PolicyProperties extends SystemProperties {
+
+ public static final String POLICY_CLIENTAUTH_VAL = "policy.ClientAuth";
+
+ public static final String POLICY_CLIENT_MECHID_VAL = "policy.client.mechId";
+
+ public static final String POLICY_CLIENT_PASSWORD_VAL = "policy.client.password";
+
+ public static final String POLICY_USERNAME_VAL = "policy.username";
+
+ public static final String POLICY_PASSWORD_VAL = "policy.password";
+
+ public static final String POLICY_AUTHORIZATION_VAL = "policy.Authorization";
+
+ public static final String POLICY_SERVER_URL_VAL = "policy.server.url";
+
+ public static final String POLICY_ENVIRONMENT_VAL = "policy.environment";
+
+ public static final String POLICY_GET_CONFIG_VAL = "policy.get.config";
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyResponseWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyResponseWrapper.java
new file mode 100644
index 000000000..02ca0f0ec
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyResponseWrapper.java
@@ -0,0 +1,56 @@
+package org.openecomp.vid.policy;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+/**
+ * This wrapper encapsulates the Policy response
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "status",
+ "entity"
+})
+
+public class PolicyResponseWrapper {
+
+ @JsonProperty("status")
+ private int status;
+
+ @JsonProperty("entity")
+ private String entity;
+
+ @JsonProperty("entity")
+ public String getEntity() {
+ return entity;
+ }
+
+ @JsonProperty("status")
+ public int getStatus() {
+ return status;
+ }
+
+ @JsonProperty("status")
+ public void setStatus(int v) {
+ this.status = v;
+ }
+
+ @JsonProperty("entity")
+ public void setEntity(String v) {
+ this.entity = v;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public String getResponse () {
+
+ StringBuilder b = new StringBuilder ("{ \"status\": ");
+ b.append(getStatus()).append(", \"entity\": " ).append(this.getEntity()).append("}");
+ return (b.toString());
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInt.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInt.java
new file mode 100644
index 000000000..7c075a535
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInt.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.policy;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.policy.rest.RequestDetails;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class PolicyRestInt {
+
+ /** The logger. */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PolicyRestInterface.class);
+
+ /** The Constant dateFormat. */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ /** The request date format. */
+ public DateFormat requestDateFormat = new SimpleDateFormat("EEE, dd MMM YYYY HH:mm:ss z");
+
+ public PolicyRestInt() {
+ requestDateFormat.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
+ }
+
+ /**
+ * Log request.
+ *
+ * @param r the r
+ */
+ public void logRequest ( RequestDetails r ) {
+ String methodName = "logRequest";
+ ObjectMapper mapper = new ObjectMapper();
+ String r_json_str = "";
+ if ( r != null ) {
+ r_json_str = r.toString();
+ try {
+ r_json_str = mapper.writeValueAsString(r);
+ }
+ catch ( com.fasterxml.jackson.core.JsonProcessingException j ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Unable to parse request as json");
+ }
+ }
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Request=(" + r_json_str + ")");
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterface.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterface.java
new file mode 100644
index 000000000..d6a59da20
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterface.java
@@ -0,0 +1,234 @@
+package org.openecomp.vid.policy;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.codec.binary.Base64;
+import org.eclipse.jetty.util.security.Password;
+import org.json.simple.JSONObject;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.client.HttpBasicClient;
+import org.openecomp.vid.policy.rest.RequestDetails;
+
+public class PolicyRestInterface extends PolicyRestInt implements PolicyRestInterfaceIfc {
+
+ /** The logger. */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PolicyRestInterface.class);
+
+ /** The Constant dateFormat. */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ /** The client. */
+ private static Client client = null;
+
+ /** The common headers. */
+ private MultivaluedHashMap<String, Object> commonHeaders;
+
+ public PolicyRestInterface() {
+ super();
+ }
+
+ public void initRestClient()
+ {
+ final String methodname = "initRestClient()";
+
+ //final String clientAuth = SystemProperties.getProperty(PolicyProperties.POLICY_CLIENTAUTH_VAL);
+ //final String authorization = SystemProperties.getProperty(PolicyProperties.POLICY_AUTHORIZATION_VAL);
+ final String mechId = SystemProperties.getProperty(PolicyProperties.POLICY_CLIENT_MECHID_VAL);
+ final String clientPassword = SystemProperties.getProperty(PolicyProperties.POLICY_CLIENT_PASSWORD_VAL);
+ final String username = SystemProperties.getProperty(PolicyProperties.POLICY_USERNAME_VAL);
+ final String password = SystemProperties.getProperty(PolicyProperties.POLICY_PASSWORD_VAL);
+ final String environment = SystemProperties.getProperty(PolicyProperties.POLICY_ENVIRONMENT_VAL);
+
+ final String decrypted_client_password = Password.deobfuscate(clientPassword);
+ String mechAuthString = mechId + ":" + decrypted_client_password;
+ byte[] mechAuthEncBytes = Base64.encodeBase64(mechAuthString.getBytes());
+ String clientAuth = new String(mechAuthEncBytes);
+
+ final String decrypted_password = Password.deobfuscate(password);
+ String authString = username + ":" + decrypted_password;
+ byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
+ String authorization = new String(authEncBytes);
+
+ commonHeaders = new MultivaluedHashMap<String, Object> ();
+ commonHeaders.put("ClientAuth", Collections.singletonList((Object) ("Basic " + clientAuth)));
+ commonHeaders.put("Authorization", Collections.singletonList((Object) ("Basic " + authorization)));
+ commonHeaders.put("Environment", Collections.singletonList((Object) (environment)));
+
+ if (client == null) {
+
+ try {
+ client = HttpBasicClient.getClient();
+ } catch (Exception e) {
+ System.out.println( methodname + " Unable to get the SSL client");
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> void Get (T t, String sourceId, String path, RestObject<T> restObject ) throws Exception {
+ String methodName = "Get";
+
+ logger.debug(EELFLoggerDelegate.debugLogger, methodName + " start");
+
+ String url="";
+ restObject.set(t);
+
+ url = SystemProperties.getProperty(PolicyProperties.POLICY_SERVER_URL_VAL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + "<== " + methodName + " sending request to url= " + url);
+
+ initRestClient();
+
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ .get();
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if (status == 200) {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ logger.debug(EELFLoggerDelegate.debugLogger, dateFormat.format(new Date()) + methodName + " REST api was successfull!");
+
+ } else {
+ throw new Exception(methodName + " with status="+ status + ", url= " + url );
+ }
+
+ logger.debug(EELFLoggerDelegate.debugLogger,methodName + " received status=" + status );
+
+ return;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> void Delete(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) {
+
+ String methodName = "Delete";
+ String url="";
+ Response cres = null;
+
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " start");
+ logRequest (r);
+
+ try {
+ initRestClient();
+
+ url = SystemProperties.getProperty(PolicyProperties.POLICY_SERVER_URL_VAL) + path;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + " methodName sending request to: " + url);
+
+ cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.entity(r)
+ .build("DELETE", Entity.entity(r, MediaType.APPLICATION_JSON)).invoke();
+ // .method("DELETE", Entity.entity(r, MediaType.APPLICATION_JSON));
+ //.delete(Entity.entity(r, MediaType.APPLICATION_JSON));
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if (status == 404) { // resource not found
+ String msg = "Resource does not exist...: " + cres.getStatus();
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + msg);
+ } else if (status == 200 || status == 204){
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + "Resource " + url + " deleted");
+ } else if (status == 202) {
+ String msg = "Delete in progress: " + status;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + msg);
+ }
+ else {
+ String msg = "Deleting Resource failed: " + status;
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + msg);
+ }
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " No response entity, this is probably ok, e="
+ + e.getMessage());
+ }
+
+ }
+ catch (Exception e)
+ {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ throw e;
+
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> void Post(T t, JSONObject requestDetails, String uuid, String path, RestObject<T> restObject) throws Exception {
+
+ String methodName = "Post";
+ String url="";
+
+ System.out.println( "POST policy rest interface");
+
+ // logRequest (requestDetails);
+ try {
+
+ initRestClient();
+
+ url = SystemProperties.getProperty(PolicyProperties.POLICY_SERVER_URL_VAL) + path;
+ System.out.println( "<== " + methodName + " sending request to url= " + url);
+ // Change the content length
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.header("content-length", 201)
+ //.header("X-FromAppId", sourceID)
+ .post(Entity.entity(requestDetails, MediaType.APPLICATION_JSON));
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+
+ System.out.println("<== " + methodName + " No response entity, this is probably ok, e=" + e.getMessage());
+ }
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if ( status >= 200 && status <= 299 ) {
+ System.out.println( "<== " + methodName + " REST api POST was successful!");
+
+ } else {
+ System.out.println( "<== " + methodName + " with status="+status+", url="+url);
+ }
+
+ } catch (Exception e)
+ {
+ System.out.println( "<== " + methodName + " with url="+url+ ", Exception: " + e.toString());
+ throw e;
+
+ }
+ }
+
+ public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException
+ {
+ return clazz.newInstance();
+ }
+
+ @Override
+ public void logRequest(RequestDetails r) {
+ // TODO Auto-generated method stub
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceFactory.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceFactory.java
new file mode 100644
index 000000000..1570875c0
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceFactory.java
@@ -0,0 +1,14 @@
+
+package org.openecomp.vid.policy;
+
+public class PolicyRestInterfaceFactory {
+
+
+ public static PolicyRestInterfaceIfc getInstance () {
+ PolicyRestInterfaceIfc obj = null;
+
+ obj = new PolicyRestInterface();
+
+ return ( obj );
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceIfc.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceIfc.java
new file mode 100644
index 000000000..f56924b36
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyRestInterfaceIfc.java
@@ -0,0 +1,58 @@
+
+package org.openecomp.vid.policy;
+
+import org.json.simple.JSONObject;
+import org.openecomp.vid.policy.rest.RequestDetails;
+
+public interface PolicyRestInterfaceIfc {
+ /**
+ * Inits the rest client.
+ */
+ public void initRestClient();
+
+ /**
+ * Gets the.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param sourceId the source id
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Get (T t, String sourceId, String path, RestObject<T> restObject ) throws Exception;
+
+ /**
+ * Delete.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param r the r
+ * @param sourceID the source ID
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Delete(T t, RequestDetails r, String sourceID, String path, RestObject<T> restObject) throws Exception;
+
+ /**
+ * Post.
+ *
+ * @param <T> the generic type
+ * @param t the t
+ * @param r the r
+ * @param sourceID the source ID
+ * @param path the path
+ * @param restObject the rest object
+ * @throws Exception the exception
+ */
+ public <T> void Post(T t, JSONObject r, String sourceID, String path, RestObject<T> restObject) throws Exception;
+
+ /***
+ * Log request.
+ *
+ * @param r the r
+ */
+ public void logRequest ( RequestDetails r );
+
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyUtil.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyUtil.java
new file mode 100644
index 000000000..ceda7c427
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/PolicyUtil.java
@@ -0,0 +1,71 @@
+package org.openecomp.vid.policy;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.glassfish.jersey.client.ClientResponse;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.policy.PolicyResponseWrapper;
+import org.openecomp.vid.policy.PolicyUtil;
+import org.openecomp.vid.policy.RestObject;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class PolicyUtil {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(PolicyUtil.class);
+
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ public static PolicyResponseWrapper wrapResponse ( String body, int statusCode ) {
+
+ PolicyResponseWrapper w = new PolicyResponseWrapper();
+ w.setStatus (statusCode);
+ w.setEntity(body);
+
+ return w;
+ }
+
+ public static PolicyResponseWrapper wrapResponse (ClientResponse cres) {
+ String resp_str = "";
+ if ( cres != null ) {
+ resp_str = cres.readEntity(String.class);
+ }
+ int statuscode = cres.getStatus();
+ PolicyResponseWrapper w = PolicyUtil.wrapResponse ( resp_str, statuscode );
+ return (w);
+ }
+
+ public static PolicyResponseWrapper wrapResponse (RestObject<String> rs) {
+ String resp_str = "";
+ int status = 0;
+ if ( rs != null ) {
+ resp_str = rs.get();
+ status = rs.getStatusCode();
+ }
+ PolicyResponseWrapper w = PolicyUtil.wrapResponse ( resp_str, status );
+ return (w);
+ }
+
+ public static <T> String convertPojoToString ( T t ) throws com.fasterxml.jackson.core.JsonProcessingException {
+
+ String methodName = "convertPojoToString";
+ ObjectMapper mapper = new ObjectMapper();
+ String r_json_str = "";
+ if ( t != null ) {
+ try {
+ r_json_str = mapper.writeValueAsString(t);
+ }
+ catch ( com.fasterxml.jackson.core.JsonProcessingException j ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Unable to parse object as json");
+ }
+ }
+ return (r_json_str);
+ }
+
+
+ public static void main(String[] args) {
+ // TODO Auto-generated method stub
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/RestObject.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/RestObject.java
new file mode 100644
index 000000000..de085f24b
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/RestObject.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.policy;
+
+/**
+ * The Class RestObject.
+ *
+ * @param <T> the generic type
+ */
+public class RestObject<T> {
+
+ /**
+ * Generic version of the RestObject class.
+ *
+ */
+ // T stands for "Type"
+ private T t;
+
+ /** The status code. */
+ private int statusCode= 0;
+
+ /**
+ * Sets the.
+ *
+ * @param t the t
+ */
+ public void set(T t) { this.t = t; }
+
+ /**
+ * Gets the.
+ *
+ * @return the t
+ */
+ public T get() { return t; }
+
+ /**
+ * Sets the status code.
+ *
+ * @param v the new status code
+ */
+ public void setStatusCode(int v) { this.statusCode = v; }
+
+ /**
+ * Gets the status code.
+ *
+ * @return the status code
+ */
+ public int getStatusCode() { return this.statusCode; }
+
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/policy/rest/RequestDetails.java b/vid-app-common/src/main/java/org/openecomp/vid/policy/rest/RequestDetails.java
new file mode 100644
index 000000000..93e80d6b3
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/policy/rest/RequestDetails.java
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.policy.rest;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+/*
+ [
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "{\"service\":\"TimeLimitAndVerticalTopology\",\"policyName\":\"SNIRO_CM_1707.Demo_TimeLimitAndVerticalTopology_zone_localTime\",\"description\":\"dev instance\",\"templateVersion\":\"1702.03\",\"version\":\"1707\",\"priority\":\"4\",\"riskType\":\"test\",\"riskLevel\":\"3\",\"guard\":\"False\",\"content\":{\"serviceType\":\"networkOnDemand\",\"identity\":\"vnf_upgrade_policy\",\"policyScope\":{\"serviceType\":[\"networkOnDemand\"],\"aicZone\":[\" \"],\"entityType\":[\"vnf\"]},\"timeSchedule\":{\"allowedPeriodicTime\":[{\"day\":\"weekday\",\"timeRange\":[{\"start_time\":\"04:00:00\",\"end_time\":\"13:00:00\"}]}]},\"nodeType\":[\"vnf\"],\"type\":\"timeLimitAndVerticalTopology\",\"conflictScope\":\"vnf_zone\"}}",
+ "policyName": "SNIRO_CM_1707.Config_MS_Demo_TimeLimitAndVerticalTopology_zone_localTime.1.xml",
+ "policyVersion": "1",
+ "matchingConditions": {
+ "ECOMPName": "SNIRO-Placement",
+ "ConfigName": "",
+ "service": "TimeLimitAndVerticalTopology",
+ "uuid": "",
+ "Location": ""
+ },
+ "responseAttributes": {},
+ "property": null
+ },
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "{\"service\":\"TimeLimitAndVerticalTopology\",\"policyName\":\"SNIRO_CM_1707.Demo_TimeLimitAndVerticalTopology_pserver_localTime\",\"description\":\"dev instance\",\"templateVersion\":\"1702.03\",\"version\":\"1707\",\"priority\":\"4\",\"riskType\":\"test\",\"riskLevel\":\"3\",\"guard\":\"False\",\"content\":{\"serviceType\":\"networkOnDemand\",\"identity\":\"vnf_upgrade_policy\",\"policyScope\":{\"serviceType\":[\"networkOnDemand\"],\"aicZone\":[\" \"],\"entityType\":[\"vnf\"]},\"timeSchedule\":{\"allowedPeriodicTime\":[{\"day\":\"weekday\",\"timeRange\":[{\"start_time\":\"04:00:00\",\"end_time\":\"13:00:00\"}]}]},\"nodeType\":[\"vnf\"],\"type\":\"timeLimitAndVerticalTopology\",\"conflictScope\":\"vnf_pserver\"}}",
+ "policyName": "SNIRO_CM_1707.Config_MS_Demo_TimeLimitAndVerticalTopology_pserver_localTime.1.xml",
+ "policyVersion": "1",
+ "matchingConditions": {
+ "ECOMPName": "SNIRO-Placement",
+ "ConfigName": "",
+ "service": "TimeLimitAndVerticalTopology",
+ "uuid": "",
+ "Location": ""
+ },
+ "responseAttributes": {},
+ "property": null
+ },
+ {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "{\"service\":\"TimeLimitAndVerticalTopology\",\"policyName\":\"SNIRO_CM_1707.Demo_TimeLimitAndVerticalTopology_vnf_localTime\",\"description\":\"dev instance\",\"templateVersion\":\"1702.03\",\"version\":\"1707\",\"priority\":\"4\",\"riskType\":\"test\",\"riskLevel\":\"3\",\"guard\":\"False\",\"content\":{\"serviceType\":\"networkOnDemand\",\"identity\":\"vnf_upgrade_policy\",\"policyScope\":{\"serviceType\":[\"networkOnDemand\"],\"aicZone\":[\" \"],\"entityType\":[\"vnf\"]},\"timeSchedule\":{\"allowedPeriodicTime\":[{\"day\":\"weekday\",\"timeRange\":[{\"start_time\":\"04:00:00\",\"end_time\":\"13:00:00\"}]}]},\"nodeType\":[\"vnf\"],\"type\":\"timeLimitAndVerticalTopology\",\"conflictScope\":\"vnf\"}}",
+ "policyName": "SNIRO_CM_1707.Config_MS_Demo_TimeLimitAndVerticalTopology_vnf_localTime.1.xml",
+ "policyVersion": "1",
+ "matchingConditions": {
+ "ECOMPName": "SNIRO-Placement",
+ "ConfigName": "",
+ "service": "TimeLimitAndVerticalTopology",
+ "uuid": "",
+ "Location": ""
+ },
+ "responseAttributes": {},
+ "property": null
+ }
+ ]
+*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "policyConfigMessage",
+ "policyConfigStatus",
+ "type",
+ "config",
+ "policyName",
+ "policyVersion",
+ "matchingConditions"
+})
+public class RequestDetails {
+
+ @JsonProperty("policyName")
+ private String policyName;
+
+ @JsonProperty("policyName")
+ public String getPolicyName() {
+ return policyName;
+ }
+
+ @JsonProperty("policyName")
+ public void setPolicyName(String policyName) {
+ this.policyName = policyName;
+ }
+
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/properties/MsoClientConfiguration.java b/vid-app-common/src/main/java/org/openecomp/vid/properties/MsoClientConfiguration.java
new file mode 100644
index 000000000..f7a331a7e
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/properties/MsoClientConfiguration.java
@@ -0,0 +1,9 @@
+package org.openecomp.vid.properties;
+
+/**
+ * Created by pickjonathan on 20/06/2017.
+ */
+public class MsoClientConfiguration {
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/roles/Role.java b/vid-app-common/src/main/java/org/openecomp/vid/roles/Role.java
index d4ded5303..f818e48fa 100644
--- a/vid-app-common/src/main/java/org/openecomp/vid/roles/Role.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/roles/Role.java
@@ -1,9 +1,9 @@
package org.openecomp.vid.roles;
-
/**
* Created by Oren on 7/1/17.
*/
+
public class Role {
private EcompRole ecompRole;
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObject.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObject.java
new file mode 100644
index 000000000..57b36830e
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObject.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.scheduler;
+
+
+public class RestObject<T> {
+
+ private T t;
+
+ private int statusCode= 0;
+
+ public String uuid;
+
+ public void set(T t) { this.t = t; }
+
+ public T get() { return t; }
+
+ public void setStatusCode(int v) { this.statusCode = v; }
+
+ public int getStatusCode() { return this.statusCode; }
+
+ public void setUUID(String uuid) { this.uuid = uuid; }
+
+ public String getUUID() { return this.uuid; }
+}
+
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/GetTimeSlotsRestObject.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/GetTimeSlotsRestObject.java
new file mode 100644
index 000000000..614b557a0
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/GetTimeSlotsRestObject.java
@@ -0,0 +1,11 @@
+package org.openecomp.vid.scheduler.RestObjects;
+
+public class GetTimeSlotsRestObject<T> extends org.openecomp.vid.scheduler.RestObject<T> {
+
+ public String uuid;
+
+ public void setUUID(String uuid) { this.uuid = uuid; }
+
+ public String getUUID() { return this.uuid; }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostCreateNewVnfRestObject.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostCreateNewVnfRestObject.java
new file mode 100644
index 000000000..86cbab8a6
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostCreateNewVnfRestObject.java
@@ -0,0 +1,10 @@
+package org.openecomp.vid.scheduler.RestObjects;
+
+public class PostCreateNewVnfRestObject<T> extends RestObject<T> {
+
+ public String uuid;
+
+ public void setUUID(String uuid) { this.uuid = uuid; }
+
+ public String getUUID() { return this.uuid; }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostSubmitVnfChangeRestObject.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostSubmitVnfChangeRestObject.java
new file mode 100644
index 000000000..6fb56f67d
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/PostSubmitVnfChangeRestObject.java
@@ -0,0 +1,10 @@
+package org.openecomp.vid.scheduler.RestObjects;
+
+public class PostSubmitVnfChangeRestObject<T> extends RestObject<T> {
+
+ public String uuid;
+
+ public void setUUID(String uuid) { this.uuid = uuid; }
+
+ public String getUUID() { return this.uuid; }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/RestObject.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/RestObject.java
new file mode 100644
index 000000000..2d0eec74d
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/RestObjects/RestObject.java
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.scheduler.RestObjects;
+
+
+public class RestObject<T> {
+
+ private T t;
+
+ private int statusCode= 0;
+
+ public void set(T t) { this.t = t; }
+
+ public T get() { return t; }
+
+ public void setStatusCode(int v) { this.statusCode = v; }
+
+ public int getStatusCode() { return this.statusCode; }
+
+}
+
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerProperties.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerProperties.java
new file mode 100644
index 000000000..15855b7be
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerProperties.java
@@ -0,0 +1,24 @@
+package org.openecomp.vid.scheduler;
+
+import org.openecomp.portalsdk.core.util.SystemProperties;
+
+
+public class SchedulerProperties extends SystemProperties {
+
+ public static final String SCHEDULER_USER_NAME_VAL = "scheduler.user.name";
+
+ public static final String SCHEDULER_PASSWORD_VAL = "scheduler.password";
+
+ public static final String SCHEDULER_SERVER_URL_VAL = "scheduler.server.url";
+
+ public static final String SCHEDULER_CREATE_NEW_VNF_CHANGE_INSTANCE_VAL = "scheduler.create.new.vnf.change.instance";
+
+ public static final String SCHEDULER_GET_TIME_SLOTS = "scheduler.get.time.slots";
+
+ public static final String SCHEDULER_SUBMIT_NEW_VNF_CHANGE = "scheduler.submit.new.vnf.change";
+
+ public static final String SCHEDULER_GET_SCHEDULES = "scheduler.get.schedules";
+
+ public static final String GET_VERSION_BY_INVARIANT_ID = "aai_get_version_by_invariant_id";
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrapper.java
new file mode 100644
index 000000000..5f148c06b
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrapper.java
@@ -0,0 +1,71 @@
+package org.openecomp.vid.scheduler;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+/**
+ * This wrapper encapsulates the Scheduler response
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "status",
+ "entity",
+ "uuid"
+})
+
+public class SchedulerResponseWrapper {
+
+ @JsonProperty("status")
+ private int status;
+
+ @JsonProperty("entity")
+ private String entity;
+
+ @JsonProperty("uuid")
+ private String uuid;
+
+ @JsonProperty("entity")
+ public String getEntity() {
+ return entity;
+ }
+
+ @JsonProperty("status")
+ public int getStatus() {
+ return status;
+ }
+
+ @JsonProperty("uuid")
+ public String getUuid() {
+ return uuid;
+ }
+
+ @JsonProperty("status")
+ public void setStatus(int v) {
+ this.status = v;
+ }
+
+ @JsonProperty("entity")
+ public void setEntity(String v) {
+ this.entity = v;
+ }
+
+ @JsonProperty("uuid")
+ public void setUuid(String v) {
+ this.uuid = v;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public String getResponse () {
+
+ StringBuilder b = new StringBuilder ("{ \"status\": ");
+ b.append(getStatus()).append(", \"entity\": \" " ).append(this.getEntity()).append("\" ,\"uuid\": \"" ).append(this.getUuid()).append("\"}");
+ return (b.toString());
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/GetTimeSlotsWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/GetTimeSlotsWrapper.java
new file mode 100644
index 000000000..e5001d41f
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/GetTimeSlotsWrapper.java
@@ -0,0 +1,5 @@
+package org.openecomp.vid.scheduler.SchedulerResponseWrappers;
+
+public class GetTimeSlotsWrapper extends SchedulerResponseWrapper {
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostCreateNewVnfWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostCreateNewVnfWrapper.java
new file mode 100644
index 000000000..f1baeaf6e
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostCreateNewVnfWrapper.java
@@ -0,0 +1,39 @@
+package org.openecomp.vid.scheduler.SchedulerResponseWrappers;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "uuid"
+})
+public class PostCreateNewVnfWrapper extends SchedulerResponseWrapper {
+
+ @JsonProperty("uuid")
+ private String uuid;
+
+ @JsonProperty("uuid")
+ public String getUuid() {
+ return uuid;
+ }
+
+ @JsonProperty("uuid")
+ public void setUuid(String v) {
+ this.uuid = v;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public String getResponse () {
+
+ StringBuilder b = new StringBuilder ("{ \"status\": ");
+ b.append(getStatus()).append(", \"entity\": \" " ).append(this.getEntity()).append("\" ,\"uuid\": \"" ).append(this.getUuid()).append("\"}");
+ return (b.toString());
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostSubmitVnfChangeTimeSlotsWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostSubmitVnfChangeTimeSlotsWrapper.java
new file mode 100644
index 000000000..86e4c0a74
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/PostSubmitVnfChangeTimeSlotsWrapper.java
@@ -0,0 +1,38 @@
+package org.openecomp.vid.scheduler.SchedulerResponseWrappers;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "uuid"
+})
+public class PostSubmitVnfChangeTimeSlotsWrapper extends SchedulerResponseWrapper {
+ @JsonProperty("uuid")
+ private String uuid;
+
+ @JsonProperty("uuid")
+ public String getUuid() {
+ return uuid;
+ }
+
+ @JsonProperty("uuid")
+ public void setUuid(String v) {
+ this.uuid = v;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public String getResponse () {
+
+ StringBuilder b = new StringBuilder ("{ \"status\": ");
+ b.append(getStatus()).append(", \"entity\": \" " ).append(this.getEntity()).append("\" ,\"uuid\": \"" ).append(this.getUuid()).append("\"}");
+ return (b.toString());
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/SchedulerResponseWrapper.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/SchedulerResponseWrapper.java
new file mode 100644
index 000000000..081ed3dc4
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerResponseWrappers/SchedulerResponseWrapper.java
@@ -0,0 +1,57 @@
+package org.openecomp.vid.scheduler.SchedulerResponseWrappers;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+/**
+ * This wrapper encapsulates the Scheduler response
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "status",
+ "entity"
+})
+
+public class SchedulerResponseWrapper {
+
+ @JsonProperty("status")
+ private int status;
+
+ @JsonProperty("entity")
+ private String entity;
+
+ @JsonProperty("entity")
+ public String getEntity() {
+ return entity;
+ }
+
+ @JsonProperty("status")
+ public int getStatus() {
+ return status;
+ }
+
+ @JsonProperty("status")
+ public void setStatus(int v) {
+ this.status = v;
+ }
+
+ @JsonProperty("entity")
+ public void setEntity(String v) {
+ this.entity = v;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this);
+ }
+
+ public String getResponse () {
+
+ StringBuilder b = new StringBuilder ("{ \"status\": ");
+
+ b.append(getStatus()).append(", \"entity\": " ).append(this.getEntity()).append("}");
+ return (b.toString());
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInt.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInt.java
new file mode 100644
index 000000000..32b3a9c8c
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInt.java
@@ -0,0 +1,42 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.scheduler;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+
+public class SchedulerRestInt {
+
+ /** The logger. */
+ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerRestInterface.class);
+
+ /** The Constant dateFormat. */
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ /** The request date format. */
+ public DateFormat requestDateFormat = new SimpleDateFormat("EEE, dd MMM YYYY HH:mm:ss z");
+
+ public SchedulerRestInt() {
+ requestDateFormat.setTimeZone(java.util.TimeZone.getTimeZone("GMT"));
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterface.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterface.java
new file mode 100644
index 000000000..5f529f390
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterface.java
@@ -0,0 +1,208 @@
+package org.openecomp.vid.scheduler;
+
+import java.util.Collections;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.Response;
+
+import org.apache.commons.codec.binary.Base64;
+import org.eclipse.jetty.util.security.Password;
+import org.json.simple.JSONObject;
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.client.HttpBasicClient;
+import org.openecomp.vid.client.HttpsBasicClient;
+import org.openecomp.vid.scheduler.SchedulerProperties;
+import org.openecomp.vid.scheduler.RestObjects.RestObject;
+import org.springframework.stereotype.Service;
+
+@Service
+public class SchedulerRestInterface implements SchedulerRestInterfaceIfc {
+
+ private static Client client = null;
+
+ private MultivaluedHashMap<String, Object> commonHeaders;
+
+ /** The logger. */
+ static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerRestInterface.class);
+
+ public SchedulerRestInterface() {
+ super();
+ }
+
+ public void initRestClient()
+ {
+ System.out.println( "\t <== Starting to initialize rest client ");
+
+ final String username;
+ final String password;
+
+ /*Setting user name based on properties*/
+ String retrievedUsername = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_USER_NAME_VAL);
+ if(retrievedUsername.isEmpty()) {
+ username = "";
+ } else {
+ username = retrievedUsername;
+ }
+
+ /*Setting password based on properties*/
+ String retrievedPassword = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_PASSWORD_VAL);
+ if(retrievedPassword.isEmpty()) {
+ password = "";
+ } else {
+ if (retrievedPassword.contains("OBF:")) {
+ password = Password.deobfuscate(retrievedPassword);
+ } else {
+ password = retrievedPassword;
+ }
+ }
+
+ String authString = username + ":" + password;
+
+ byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
+ String authStringEnc = new String(authEncBytes);
+
+ commonHeaders = new MultivaluedHashMap<String, Object> ();
+ commonHeaders.put("Authorization", Collections.singletonList((Object) ("Basic " + authStringEnc)));
+
+ try {
+ if ( !username.isEmpty() ) {
+
+ client = HttpsBasicClient.getClient();
+ }
+ else {
+
+ client = HttpBasicClient.getClient();
+ }
+ } catch (Exception e) {
+ System.out.println( " <== Unable to initialize rest client ");
+ }
+
+ System.out.println( "\t<== Client Initialized \n");
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> void Get (T t, String sourceId, String path, org.openecomp.vid.scheduler.RestObject<T> restObject ) throws Exception {
+
+ String methodName = "Get";
+ String url = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_SERVER_URL_VAL) + path;
+
+
+ System.out.println( "<== URL FOR GET : " + url + "\n");
+
+ initRestClient();
+
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ .get();
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if (status == 200) {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+
+ } else {
+ throw new Exception(methodName + " with status="+ status + ", url= " + url );
+ }
+
+ return;
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> void Post(T t, JSONObject requestDetails, String path, RestObject<T> restObject) throws Exception {
+
+ String methodName = "Post";
+ String url = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_SERVER_URL_VAL) + path;
+
+ System.out.println( "<== URL FOR POST : " + url + "\n");
+
+ try {
+
+ initRestClient();
+
+ // Change the content length
+ final Response cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ .post(Entity.entity(requestDetails, MediaType.APPLICATION_JSON));
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+
+ System.out.println("<== " + methodName + " : No response entity, this is probably ok, e=" + e.getMessage());
+ }
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ if ( status >= 200 && status <= 299 ) {
+
+ System.out.println( "<== " + methodName + " : REST api POST was successful!" + "\n");
+
+ } else {
+ System.out.println( "<== " + methodName + " : FAILED with http status : "+status+", url = " + url + "\n");
+ }
+
+ } catch (Exception e)
+ {
+ System.out.println( "<== " + methodName + " : with url="+url+ ", Exception: " + e.toString() + "\n");
+ throw e;
+ }
+ }
+
+ @Override
+ public void logRequest(JSONObject requestDetails) {}
+
+ @SuppressWarnings("unchecked")
+ public <T> void Delete(T t, JSONObject requestDetails, String sourceID, String path, RestObject<T> restObject) {
+
+ String url="";
+ Response cres = null;
+
+ try {
+ initRestClient();
+
+ url = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_SERVER_URL_VAL) + path;
+
+ cres = client.target(url)
+ .request()
+ .accept("application/json")
+ .headers(commonHeaders)
+ //.entity(r)
+ .build("DELETE", Entity.entity(requestDetails, MediaType.APPLICATION_JSON)).invoke();
+ // .method("DELETE", Entity.entity(r, MediaType.APPLICATION_JSON));
+ //.delete(Entity.entity(r, MediaType.APPLICATION_JSON));
+
+ int status = cres.getStatus();
+ restObject.setStatusCode (status);
+
+ try {
+ t = (T) cres.readEntity(t.getClass());
+ restObject.set(t);
+ }
+ catch ( Exception e ) {
+ }
+
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ }
+
+ public <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException
+ {
+ return clazz.newInstance();
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceFactory.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceFactory.java
new file mode 100644
index 000000000..bf7bd8891
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceFactory.java
@@ -0,0 +1,15 @@
+
+package org.openecomp.vid.scheduler;
+
+public class SchedulerRestInterfaceFactory {
+
+
+ public static SchedulerRestInterfaceIfc getInstance () {
+ SchedulerRestInterfaceIfc obj = null;
+
+ obj = new SchedulerRestInterface();
+
+ return ( obj );
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceIfc.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceIfc.java
new file mode 100644
index 000000000..839ab348d
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerRestInterfaceIfc.java
@@ -0,0 +1,21 @@
+
+package org.openecomp.vid.scheduler;
+
+import org.json.simple.JSONObject;
+import org.openecomp.vid.scheduler.RestObjects.RestObject;
+import org.springframework.stereotype.Service;
+
+@Service
+public interface SchedulerRestInterfaceIfc {
+
+ public void initRestClient();
+
+ public <T> void Get (T t, String sourceId, String path, org.openecomp.vid.scheduler.RestObject<T> restObject ) throws Exception;
+
+ public <T> void Delete(T t, JSONObject requestDetails, String sourceID, String path, RestObject<T> restObject)
+ throws Exception;
+
+ public <T> void Post(T t, JSONObject r, String path, RestObject<T> restObject) throws Exception;
+
+ public void logRequest(JSONObject requestDetails);
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerUtil.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerUtil.java
new file mode 100644
index 000000000..f82f474f6
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/SchedulerUtil.java
@@ -0,0 +1,100 @@
+package org.openecomp.vid.scheduler;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.scheduler.SchedulerResponseWrappers.GetTimeSlotsWrapper;
+import org.openecomp.vid.scheduler.SchedulerResponseWrappers.PostCreateNewVnfWrapper;
+import org.openecomp.vid.scheduler.SchedulerResponseWrappers.PostSubmitVnfChangeTimeSlotsWrapper;
+import org.openecomp.vid.scheduler.SchedulerUtil;
+import org.openecomp.vid.scheduler.RestObjects.GetTimeSlotsRestObject;
+import org.openecomp.vid.scheduler.RestObjects.PostCreateNewVnfRestObject;
+import org.openecomp.vid.scheduler.RestObjects.PostSubmitVnfChangeRestObject;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class SchedulerUtil {
+
+ private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(SchedulerUtil.class);
+
+ final static DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss:SSSS");
+
+ public static GetTimeSlotsWrapper getTimeSlotsWrapResponse (GetTimeSlotsRestObject<String> rs) {
+
+ String resp_str = "";
+ int status = 0;
+
+ if ( rs != null ) {
+ resp_str = rs.get();
+ status = rs.getStatusCode();
+ }
+
+ GetTimeSlotsWrapper w = new GetTimeSlotsWrapper();
+
+ w.setEntity(resp_str);
+ w.setStatus (status);
+
+ return (w);
+ }
+
+ public static PostSubmitVnfChangeTimeSlotsWrapper postSubmitNewVnfWrapResponse (PostSubmitVnfChangeRestObject<String> rs) {
+
+ String resp_str = "";
+ int status = 0;
+ String uuid = "";
+
+ if ( rs != null ) {
+ resp_str = rs.get();
+ status = rs.getStatusCode();
+ uuid = rs.getUUID();
+ }
+
+ PostSubmitVnfChangeTimeSlotsWrapper w = new PostSubmitVnfChangeTimeSlotsWrapper();
+
+ w.setEntity(resp_str);
+ w.setStatus (status);
+ w.setUuid(uuid);
+
+ return (w);
+ }
+
+ public static PostCreateNewVnfWrapper postCreateNewVnfWrapResponse (PostCreateNewVnfRestObject<String> rs) {
+
+ String resp_str = "";
+ int status = 0;
+ String uuid = "";
+
+ if ( rs != null ) {
+ resp_str = rs.get();
+ status = rs.getStatusCode();
+ uuid = rs.getUUID();
+ }
+
+ PostCreateNewVnfWrapper w = new PostCreateNewVnfWrapper();
+
+ w.setEntity(resp_str);
+ w.setStatus (status);
+ w.setUuid(uuid);
+
+ return (w);
+ }
+
+ public static <T> String convertPojoToString ( T t ) throws com.fasterxml.jackson.core.JsonProcessingException {
+
+ String methodName = "convertPojoToString";
+ ObjectMapper mapper = new ObjectMapper();
+ String r_json_str = "";
+ if ( t != null ) {
+ try {
+ r_json_str = mapper.writeValueAsString(t);
+ }
+ catch ( com.fasterxml.jackson.core.JsonProcessingException j ) {
+ logger.debug(EELFLoggerDelegate.debugLogger,dateFormat.format(new Date()) + "<== " + methodName + " Unable to parse object as json");
+ }
+ }
+ return (r_json_str);
+ }
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/scheduler/rest/RequestDetails.java b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/rest/RequestDetails.java
new file mode 100644
index 000000000..746fd9b24
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/scheduler/rest/RequestDetails.java
@@ -0,0 +1,106 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.vid.scheduler.rest;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.List;
+//import javax.annotation.Generated;
+
+import org.openecomp.vid.domain.mso.CloudConfiguration;
+import org.openecomp.vid.domain.mso.ModelInfo;
+import org.openecomp.vid.domain.mso.RequestInfo;
+import org.openecomp.vid.domain.mso.RequestParameters;
+import org.openecomp.vid.domain.mso.SubscriberInfo;
+import com.fasterxml.jackson.annotation.JsonAnyGetter;
+import com.fasterxml.jackson.annotation.JsonAnySetter;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+/*
+ * "domain" : "ChangeManagement",
+ "scheduleId" : "3569b875-d40e-4adb-a288-a74f4b59ec1c",
+ "scheduleName" : "VnfUpgrade/DWF",
+ "userId" : "jf9860@att.com",
+ "domainData" : {
+ "WorkflowName" : "HEAT Stack Software Update for vNFs"
+ },
+ "status" : "PendingOptimization",
+ "schedulingInfo" : {
+ "scheduleId" : "ChangeManagement.3569b875-d40e-4adb-a288-a74f4b59ec1c",
+ "normalDurationInSecs" : 60,
+ "AdditionalDurationInSecs" : 0,
+ "concurrencyLimit" : 10,
+ "policyId" : ["SNIRO.TimeLimitAndVerticalTopology"],
+ "groups" : [{
+ "groupId" : " group1",
+ "node" : ["satmo415vbc", "satmo455vbc"],
+ "changeWindows" : [{
+ "startTime" : "2017-02-15T01:00:00Z",
+ "finishTime" : "2017-02-15T02:00:00Z"
+ }
+ ]
+ }, {
+ "groupId" : " group2",
+ "node" : ["satmo555vbc"],
+ "changeWindows" : [{
+ "startTime" : "2017-02-15T01:00:00Z",
+ "finishTime" : "2017-02-15T02:00:00Z"
+ }, {
+ "startTime" : "2017-02-15T05:00:00Z",
+ "finishTime" : "2017-02-15T05:30:00Z"
+ }
+ ]
+ }
+ ]
+*/
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonPropertyOrder({
+ "domain",
+ "scheduleId",
+ "scheduleName",
+ "userId",
+ "domainData",
+ "status",
+ "schcedulingInfo"
+})
+public class RequestDetails {
+
+ @JsonProperty("domain")
+ private String domain;
+
+
+
+ @JsonProperty("domain")
+ public String getDomain() {
+ return domain;
+ }
+
+ @JsonProperty("domain")
+ public void setDomain(String domain) {
+ this.domain = domain;
+ }
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/services/AaiService.java b/vid-app-common/src/main/java/org/openecomp/vid/services/AaiService.java
index 274419fb8..d3bacadec 100644
--- a/vid-app-common/src/main/java/org/openecomp/vid/services/AaiService.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/services/AaiService.java
@@ -5,6 +5,7 @@ import org.openecomp.vid.aai.SubscriberFilteredResults;
import org.openecomp.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.openecomp.vid.roles.RoleValidator;
+import javax.ws.rs.core.Response;
import java.util.List;
/**
@@ -21,5 +22,13 @@ public interface AaiService {
AaiResponse getAaiZones();
+ AaiResponse getAicZoneForPnf(String globalCustomerId , String serviceType , String serviceId);
+
+ Response getVNFData(String globalSubscriberId, String serviceType);
+
AaiResponse<GetTenantsResponse[]> getTenants(String globalCustomerId, String serviceType, RoleValidator roleValidator);
+
+ AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId);
+
+ Response getVersionByInvariantId(List<String> modelInvariantId);
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/services/AaiServiceImpl.java b/vid-app-common/src/main/java/org/openecomp/vid/services/AaiServiceImpl.java
index 38b670fe5..cb0962869 100644
--- a/vid-app-common/src/main/java/org/openecomp/vid/services/AaiServiceImpl.java
+++ b/vid-app-common/src/main/java/org/openecomp/vid/services/AaiServiceImpl.java
@@ -1,12 +1,17 @@
package org.openecomp.vid.services;
import org.ecomp.aai.model.AaiAICZones.AicZones;
+import org.openecomp.portalsdk.core.util.SystemProperties;
import org.openecomp.vid.aai.*;
import org.openecomp.vid.aai.model.AaiGetServicesRequestModel.*;
import org.openecomp.vid.aai.model.AaiGetTenatns.GetTenantsResponse;
import org.openecomp.vid.model.*;
import org.openecomp.vid.roles.RoleValidator;
+import org.openecomp.vid.scheduler.SchedulerProperties;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+
+import javax.ws.rs.core.Response;
import java.util.List;
@@ -37,13 +42,23 @@ public class AaiServiceImpl implements AaiService {
String subscriberGlobalId = subscriberResponse.getT().globalCustomerId;
for (ServiceSubscription serviceSubscription : subscriberResponse.getT().serviceSubscriptions.serviceSubscription) {
String serviceType = serviceSubscription.serviceType;
- serviceSubscription.isPermitted = roleProvider.isServicePermitted(subscriberGlobalId,serviceType);;
+ serviceSubscription.isPermitted = roleProvider.isServicePermitted(subscriberGlobalId,serviceType);
}
return subscriberResponse;
}
@Override
+ public Response getVersionByInvariantId(List<String> modelInvariantId) {
+ try {
+ return aaiClient.getVersionByInvariantId(modelInvariantId);
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
public AaiResponse getServices(RoleValidator roleValidator) {
AaiResponse<GetServicesAAIRespone> subscriberResponse = aaiClient.getServices();
for (org.openecomp.vid.aai.model.AaiGetServicesRequestModel.Service service :subscriberResponse.getT().service){
@@ -62,9 +77,25 @@ public class AaiServiceImpl implements AaiService {
return aaiGetTenantsResponse;
}
- @Override
+ @Override
+ public AaiResponse getVNFData(String globalSubscriberId, String serviceType, String serviceInstanceId) {
+ return aaiClient.getVNFData(globalSubscriberId,serviceType,serviceInstanceId);
+ }
+
+ @Override
+ public Response getVNFData(String globalSubscriberId, String serviceType) {
+ return aaiClient.getVNFData(globalSubscriberId,serviceType);
+ }
+
+ @Override
public AaiResponse getAaiZones() {
AaiResponse<AicZones> response = aaiClient.getAllAicZones();
return response;
}
+
+ @Override
+ public AaiResponse getAicZoneForPnf(String globalCustomerId , String serviceType , String serviceId) {
+ AaiResponse<AicZones> response = aaiClient.getAicZoneForPnf(globalCustomerId , serviceType , serviceId);
+ return response;
+ }
}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementService.java b/vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementService.java
new file mode 100644
index 000000000..3ac528282
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementService.java
@@ -0,0 +1,14 @@
+package org.openecomp.vid.services;
+
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
+import org.json.simple.JSONArray;
+import org.openecomp.vid.mso.rest.Request;
+import org.springframework.http.ResponseEntity;
+
+import java.util.Collection;
+
+public interface ChangeManagementService {
+ Collection<Request> getMSOChangeManagements();
+ ResponseEntity<String> doChangeManagement(ChangeManagementRequest request, String vnfName);
+ JSONArray getSchedulerChangeManagements();
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementServiceImpl.java b/vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementServiceImpl.java
new file mode 100644
index 000000000..7e69d8fec
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/services/ChangeManagementServiceImpl.java
@@ -0,0 +1,109 @@
+package org.openecomp.vid.services;
+
+import org.openecomp.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
+import org.openecomp.vid.changeManagement.RequestDetails;
+import org.openecomp.vid.mso.MsoBusinessLogic;
+import org.openecomp.vid.mso.MsoResponseWrapper;
+import org.openecomp.vid.controller.MsoController;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.scheduler.*;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.openecomp.vid.mso.rest.Request;
+import org.springframework.stereotype.Service;
+import org.json.simple.JSONArray;
+import org.json.simple.parser.JSONParser;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Collection;
+
+
+@Service
+public class ChangeManagementServiceImpl implements ChangeManagementService {
+ @Override
+ public Collection<Request> getMSOChangeManagements() {
+ Collection<Request> result = null;
+ MsoBusinessLogic msoBusinessLogic = new MsoBusinessLogic();
+ try {
+ result = msoBusinessLogic.getOrchestrationRequestsForDashboard();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ private RequestDetails findRequestByVnfName(List<RequestDetails> requests, String vnfName){
+
+ if (requests == null)
+ return null;
+
+ for(RequestDetails requestDetails: requests){
+ if(requestDetails.getVnfName().equals(vnfName)){
+ return requestDetails;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public ResponseEntity<String> doChangeManagement(ChangeManagementRequest request, String vnfName) {
+ if (request == null)
+ return null;
+ ResponseEntity<String> response = null;
+ RequestDetails currentRequestDetails = findRequestByVnfName(request.getRequestDetails(), vnfName);
+ MsoResponseWrapper msoResponseWrapperObject = null;
+ if(currentRequestDetails != null){
+ MsoBusinessLogic msoBusinessLogicObject = new MsoBusinessLogic();
+ String serviceInstanceId = currentRequestDetails.getRelatedInstList().get(0).getRelatedInstance().getInstanceId();
+ String vnfInstanceId = currentRequestDetails.getVnfInstanceId();
+ try {
+ if (request.getRequestType().equalsIgnoreCase("update")) {
+
+ msoResponseWrapperObject = msoBusinessLogicObject.updateVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
+ }
+ else if (request.getRequestType().equalsIgnoreCase("replace"))
+ {
+ msoResponseWrapperObject = msoBusinessLogicObject.replaceVnf(currentRequestDetails, serviceInstanceId, vnfInstanceId);
+// throw new NotImplementedException();
+ }
+ response = new ResponseEntity<String>(msoResponseWrapperObject.getResponse(), HttpStatus.OK);
+ return response;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ // AH:TODO: return ChangeManagementResponse
+ return null;
+ }
+
+ @Override
+ public JSONArray getSchedulerChangeManagements() {
+ JSONArray result = null;
+ try {
+ String path = SystemProperties.getProperty(SchedulerProperties.SCHEDULER_GET_SCHEDULES);
+ org.openecomp.vid.scheduler.RestObject<String> restObject = new org.openecomp.vid.scheduler.RestObject<>();
+ SchedulerRestInterfaceIfc restClient = SchedulerRestInterfaceFactory.getInstance();
+
+ String str = new String();
+ restObject.set(str);
+ restClient.Get(str, "", path, restObject);
+ String restCallResult = restObject.get();
+ JSONParser parser = new JSONParser();
+ Object parserResult = parser.parse(restCallResult);
+ result = (JSONArray) parserResult;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowService.java b/vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowService.java
new file mode 100644
index 000000000..7f43433de
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowService.java
@@ -0,0 +1,9 @@
+package org.openecomp.vid.services;
+
+import org.openecomp.vid.model.Workflow;
+import java.util.Collection;
+
+public interface WorkflowService {
+ Collection<String> getWorkflowsForVNFs(Collection<String> vnfNames);
+ Collection<String> getAllWorkflows();
+}
diff --git a/vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowServiceImpl.java b/vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowServiceImpl.java
new file mode 100644
index 000000000..deb506069
--- /dev/null
+++ b/vid-app-common/src/main/java/org/openecomp/vid/services/WorkflowServiceImpl.java
@@ -0,0 +1,40 @@
+package org.openecomp.vid.services;
+
+import org.openecomp.vid.model.Workflow;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+@Service
+public class WorkflowServiceImpl implements WorkflowService {
+ //TODO: Add the list of workflows hard coded or from DB.
+ private ArrayList<Workflow> workflows = new ArrayList<>(Arrays.asList(
+ new Workflow(0, "Upgrade", new ArrayList<>(Arrays.asList("VNF1", "VNF2", "VNF3", "VNF4"))),
+ new Workflow(1, "Clean", new ArrayList<>(Arrays.asList("VNF1", "VNF2", "VNF3"))),
+ new Workflow(2, "Reinstall", new ArrayList<>(Arrays.asList("VNF1", "VNF2", "VNF4"))),
+ new Workflow(3, "Dump", new ArrayList<>(Arrays.asList("VNF1", "VNF3", "VNF4"))),
+ new Workflow(4, "Flush", new ArrayList<>(Arrays.asList("VNF2", "VNF3", "VNF4")))
+ ));
+
+ @Override
+ public Collection<String> getWorkflowsForVNFs(Collection<String> vnfNames) {
+ Collection<String> result = workflows.stream()
+ .filter(workflow -> workflow.getVnfNames().containsAll(vnfNames))
+ .map(workflow -> workflow.getWorkflowName())
+ .distinct()
+ .collect(Collectors.toList());
+
+ return result;
+ }
+
+ @Override
+ public Collection<String> getAllWorkflows() {
+ return workflows.stream()
+ .map(workflow -> workflow.getWorkflowName())
+ .distinct()
+ .collect(Collectors.toList());
+ }
+}
diff --git a/vid-app-common/src/main/resources/json/mso/modelInfo b/vid-app-common/src/main/resources/json/mso/modelInfo
index 2504d517b..dcb31128d 100755
--- a/vid-app-common/src/main/resources/json/mso/modelInfo
+++ b/vid-app-common/src/main/resources/json/mso/modelInfo
@@ -7,11 +7,19 @@
"description": "reference to the customized set of parameters associated with a model in a given service context",
"type": "string"
},
+ "modelCustomizationId": {
+ "description": "reference to the customized set of parameters associated with a model in a given service context",
+ "type": "string"
+ },
"modelInvariantId": {
"description": "Invariant UUID for the model name, irrespective of the version, as defined in SDC--authoritative",
"type": "string",
"pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$"
},
+ "modelVersionId": {
+ "description": "Version id for version",
+ "type": "string"
+ },
"modelName": {
"description": "name of the model as defined in SDC--not authoritative",
"type": "string"
@@ -29,12 +37,13 @@
"service",
"vfModule",
"vnf",
- "volumeGroup"
+ "volumeGroup",
+ "configuration"
]
},
"modelVersion": {
"description": "the version of the model as defined in SDC--not authoritative",
- "type": "number"
+ "type": "string"
}
},
"required": ["modelType"]
diff --git a/vid-app-common/src/main/resources/json/mso/request b/vid-app-common/src/main/resources/json/mso/request
index 3aaadbfbc..95720bf91 100755
--- a/vid-app-common/src/main/resources/json/mso/request
+++ b/vid-app-common/src/main/resources/json/mso/request
@@ -22,7 +22,9 @@
"service",
"vfModule",
"vnf",
- "volumeGroup"
+ "volumeGroup",
+ "unknown",
+ "configuration"
]
},
"requestStatus": {},
@@ -33,7 +35,11 @@
"createInstance",
"deleteInstance",
"replaceInstance",
- "updateInstance"
+ "updateInstance",
+ "activateInstance",
+ "deactivateInstance",
+ "unknown",
+ "not provided"
]
},
"startTime": {
diff --git a/vid-app-common/src/main/resources/json/mso/requestInfo b/vid-app-common/src/main/resources/json/mso/requestInfo
index 56db42fce..5fcf74c7c 100755
--- a/vid-app-common/src/main/resources/json/mso/requestInfo
+++ b/vid-app-common/src/main/resources/json/mso/requestInfo
@@ -37,6 +37,14 @@
"suppressRollback": {
"description": "true or false boolean indicating whether rollbacks should be suppressed on failures",
"type": "boolean"
+ },
+ "responseValue": {
+ "description": "Is the user selected value based on the validResponses list provided to complete the manual task",
+ "type": "string"
+ },
+ "requestorId": {
+ "description": "The id of the person who initiated the completion request",
+ "type": "string"
}
},
diff --git a/vid-app-common/src/main/resources/json/mso/requestStatus b/vid-app-common/src/main/resources/json/mso/requestStatus
index 9eacb6bb1..11b285636 100755
--- a/vid-app-common/src/main/resources/json/mso/requestStatus
+++ b/vid-app-common/src/main/resources/json/mso/requestStatus
@@ -9,9 +9,13 @@
"requestState": {
"description": "short description of the instantiation state",
"enum": [
- "complete",
- "failed",
- "inProgress"
+ "COMPLETE",
+ "FAILED",
+ "IN_PROGRESS",
+ "PENDING",
+ "UNLOCKED",
+ "COMPLETED",
+ ""
],
"type": "string"
},
diff --git a/vid-app-common/src/main/resources/mso_complete_manual_task.json b/vid-app-common/src/main/resources/mso_complete_manual_task.json
new file mode 100644
index 000000000..625c9d9d0
--- /dev/null
+++ b/vid-app-common/src/main/resources/mso_complete_manual_task.json
@@ -0,0 +1,5 @@
+{
+ "taskRequestReference": {
+ "taskId": "daf4dd84-b77a-42da-a051-3239b7a9392c"
+ }
+}
diff --git a/vid-app-common/src/main/resources/mso_create_instance_response.json b/vid-app-common/src/main/resources/mso_create_instance_response.json
new file mode 100644
index 000000000..19763bc9a
--- /dev/null
+++ b/vid-app-common/src/main/resources/mso_create_instance_response.json
@@ -0,0 +1,6 @@
+{
+ "requestReferences": {
+ "instanceId": "ba00de9b-3c3e-4b0a-a1ad-0c5489e711fb",
+ "requestId": "311cc766-b673-4a50-b9c5-471f68914586"
+ }
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/resources/mso_get_manual_task_by_request_id.json b/vid-app-common/src/main/resources/mso_get_manual_task_by_request_id.json
new file mode 100644
index 000000000..004280bce
--- /dev/null
+++ b/vid-app-common/src/main/resources/mso_get_manual_task_by_request_id.json
@@ -0,0 +1,23 @@
+{
+ "taskList":[
+ {
+ "taskId":"daf4dd84-b77a-42da-a051-3239b7a9392c",
+ "type":"fallout",
+ "nfRole":"vSCP",
+ "subscriptionServiceType":"Mobility",
+ "originalRequestId":"za1234d1-5a33-55df-13ab-12abad84e335",
+ "originalRequestorId":"ss835w",
+ "errorSource":"A&AI",
+ "errorCode":"404",
+ "errorMessage":"Failed in A&AI 404",
+ "buildingBlockName":"DoCreateVfModule",
+ "buildingBlockStep":"invokeA&AI:getTenant",
+ "validResponses":[
+ "rollback",
+ "abort",
+ "skip",
+ "retry"
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/resources/mso_get_orchestration_requests.json b/vid-app-common/src/main/resources/mso_get_orchestration_requests.json
new file mode 100644
index 000000000..430ebc498
--- /dev/null
+++ b/vid-app-common/src/main/resources/mso_get_orchestration_requests.json
@@ -0,0 +1,88 @@
+{
+ "requestList":[
+ {
+ "request":{
+ "requestId":"25272f7e-74c6-4afc-966a-4587f2c30bae",
+ "startTime":"Mon, 31 Jul 2017 23:25:30 GMT",
+ "requestScope":"vnf",
+ "requestType":"updateInstance",
+ "requestDetails":null,
+ "instanceReferences":{
+ "serviceInstanceId":null,
+ "serviceInstanceName":null,
+ "vnfInstanceId":null,
+ "vnfInstanceName":null,
+ "vfModuleInstanceId":null,
+ "vfModuleInstanceName":null,
+ "volumeGroupInstanceId":null,
+ "volumeGroupInstanceName":null,
+ "networkInstanceId":null,
+ "networkInstanceName":null,
+ "requestorId":"md5621"
+ },
+ "requestStatus":{
+ "requestState":"IN_PROGRESS",
+ "statusMessage":null,
+ "percentProgress":20,
+ "finishTime":null
+ }
+ }
+ },
+ {
+ "request":{
+ "requestId":"25272f7e-74c6-4afc-966a-4587f2c30bae",
+ "startTime":"Mon, 31 Jul 2017 23:25:30 GMT",
+ "requestScope":"service",
+ "requestType":"createInstance",
+ "requestDetails":null,
+ "instanceReferences":{
+ "serviceInstanceId":null,
+ "serviceInstanceName":null,
+ "vnfInstanceId":null,
+ "vnfInstanceName":null,
+ "vfModuleInstanceId":null,
+ "vfModuleInstanceName":null,
+ "volumeGroupInstanceId":null,
+ "volumeGroupInstanceName":null,
+ "networkInstanceId":null,
+ "networkInstanceName":null,
+ "requestorId":"md5621"
+ },
+ "requestStatus":{
+ "requestState":"IN_PROGRESS",
+ "statusMessage":null,
+ "percentProgress":20,
+ "finishTime":null
+ }
+ }
+ },
+ {
+ "request":{
+ "requestId":"9d6819e1-76e6-4e28-ad08-367632f41c7e",
+ "startTime":"Fri, 20 May 2016 19:07:57 GMT",
+ "requestScope":"vnf",
+ "requestType":"replaceInstance",
+ "requestDetails":null,
+ "instanceReferences":{
+ "serviceInstanceId":null,
+ "serviceInstanceName":null,
+ "vnfInstanceId":null,
+ "vnfInstanceName":null,
+ "vfModuleInstanceId":null,
+ "vfModuleInstanceName":null,
+ "volumeGroupInstanceId":null,
+ "volumeGroupInstanceName":null,
+ "networkInstanceId":null,
+ "networkInstanceName":null,
+ "requestorId":null
+ },
+ "requestStatus":{
+ "requestState":"FAILED",
+ "statusMessage":"Service request FAILED schema validation. No valid format for volume request is specified",
+ "percentProgress":100,
+ "finishTime":"Fri, 20 May 2016 19:07:57 GMT"
+ }
+ }
+ }
+ ]
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/css/bootstrap.min.css b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/css/bootstrap.min.css
new file mode 100644
index 000000000..ed3905e0e
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/css/bootstrap.min.css
@@ -0,0 +1,6 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
+/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.eot b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 000000000..b93a4953f
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.eot
Binary files differ
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.svg b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 000000000..94fb5490a
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,288 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph horiz-adv-x="0" />
+<glyph horiz-adv-x="400" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
+<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
+<glyph unicode="&#x2000;" horiz-adv-x="650" />
+<glyph unicode="&#x2001;" horiz-adv-x="1300" />
+<glyph unicode="&#x2002;" horiz-adv-x="650" />
+<glyph unicode="&#x2003;" horiz-adv-x="1300" />
+<glyph unicode="&#x2004;" horiz-adv-x="433" />
+<glyph unicode="&#x2005;" horiz-adv-x="325" />
+<glyph unicode="&#x2006;" horiz-adv-x="216" />
+<glyph unicode="&#x2007;" horiz-adv-x="216" />
+<glyph unicode="&#x2008;" horiz-adv-x="162" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="325" />
+<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
+<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
+<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
+<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
+<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
+<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
+<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
+<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
+<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
+<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
+<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
+<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
+<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
+<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
+<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
+<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
+<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
+<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
+<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
+<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
+<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
+<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
+<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
+<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
+<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
+<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
+<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
+<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
+<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
+<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
+<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
+<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
+<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
+<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
+<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
+<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
+<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
+<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
+<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
+<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
+<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
+<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
+<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
+<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
+<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
+<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
+<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
+<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
+<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
+<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
+<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
+<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
+<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
+<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
+<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
+<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
+<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
+<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
+<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
+<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
+<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
+<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
+<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
+<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
+<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
+<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
+<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
+<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
+<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
+<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
+<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
+<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
+<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
+<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
+<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
+<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
+<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
+<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
+<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
+<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
+<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
+<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
+<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
+<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
+<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
+<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
+<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
+<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
+<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
+<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
+<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
+<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
+<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
+<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
+<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
+<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
+<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
+<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
+<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
+<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
+<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
+<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
+<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
+<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
+<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
+<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
+<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
+<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
+<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
+<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
+<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
+<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
+<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
+<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
+<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
+<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
+<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
+<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
+<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
+<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
+<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
+<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
+<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
+<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
+<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
+<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
+<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
+<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
+<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
+<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
+<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
+<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
+<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
+<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
+<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
+<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
+<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
+<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
+<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
+<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
+<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
+<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
+<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
+<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
+<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
+<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
+<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
+<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
+<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
+<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
+<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
+<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
+<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
+<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
+<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
+<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
+<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
+<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
+<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
+<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
+<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
+<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
+<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
+<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
+<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
+<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
+<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
+<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
+<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
+<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
+<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
+<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
+<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
+<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
+<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
+<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
+<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
+<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
+<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
+<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
+<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
+<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
+<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
+<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
+<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
+<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
+<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
+<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
+<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
+</font>
+</defs></svg> \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.ttf b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 000000000..1413fc609
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.ttf
Binary files differ
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 000000000..9e612858f
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff
Binary files differ
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff2 b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff2
new file mode 100644
index 000000000..64539b54c
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/fonts/glyphicons-halflings-regular.woff2
Binary files differ
diff --git a/vid-app-common/src/main/webapp/app/vid/external/bootstrap/js/bootstrap.min.js b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/js/bootstrap.min.js
new file mode 100644
index 000000000..9bcd2fcca
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/bootstrap/js/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.7 (http://getbootstrap.com)
+ * Copyright 2011-2016 Twitter, Inc.
+ * Licensed under the MIT license
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){document===a.target||this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);if(this.$element.trigger(g),!g.isDefaultPrevented())return f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=window.SVGElement&&c instanceof window.SVGElement,g=d?{top:0,left:0}:f?null:b.offset(),h={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},i=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,h,i,g)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){
+this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.7",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e<c&&"top";if("bottom"==this.affixed)return null!=c?!(e+this.unpin<=f.top)&&"bottom":!(e+g<=a-d)&&"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&e<=c?"top":null!=d&&i+j>=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ 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
new file mode 100644
index 000000000..ca447f4e8
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/lodash/lodash.min.js
@@ -0,0 +1,136 @@
+/**
+ * @license
+ * Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
+ */
+;(function(){function n(n,t){return n.set(t[0],t[1]),n}function t(n,t){return n.add(t),n}function r(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function e(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u<i;){var o=n[u];t(e,o,r(o),n)}return e}function u(n,t){for(var r=-1,e=null==n?0:n.length;++r<e&&false!==t(n[r],r,n););return n}function i(n,t){for(var r=null==n?0:n.length;r--&&false!==t(n[r],r,n););
+return n}function o(n,t){for(var r=-1,e=null==n?0:n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function f(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 c(n,t){return!(null==n||!n.length)&&-1<d(n,t,0)}function a(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 l(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 s(n,t){for(var r=-1,e=t.length,u=n.length;++r<e;)n[u+r]=t[r];
+return n}function h(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 p(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 _(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 v(n,t,r){var e;return r(n,function(n,r,u){if(t(n,r,u))return e=r,false}),e}function g(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 d(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=g(n,b,r);return n}function y(n,t,r,e){--r;for(var u=n.length;++r<u;)if(e(n[r],t))return r;return-1}function b(n){return n!==n}function x(n,t){var r=null==n?0:n.length;return r?k(n,t)/r:P}function j(n){return function(t){return null==t?F:t[n]}}function w(n){return function(t){return null==n?F:n[t]}}function m(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function A(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;
+return n}function k(n,t){for(var r,e=-1,u=n.length;++e<u;){var i=t(n[e]);i!==F&&(r=r===F?i:r+i)}return r}function E(n,t){for(var r=-1,e=Array(n);++r<n;)e[r]=t(r);return e}function O(n,t){return l(t,function(t){return[t,n[t]]})}function S(n){return function(t){return n(t)}}function I(n,t){return l(t,function(t){return n[t]})}function R(n,t){return n.has(t)}function z(n,t){for(var r=-1,e=n.length;++r<e&&-1<d(t,n[r],0););return r}function W(n,t){for(var r=n.length;r--&&-1<d(t,n[r],0););return r}function B(n){
+return"\\"+Tn[n]}function L(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 C(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 D(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=n}),r}function M(n){var t=-1,r=Array(n.size);return n.forEach(function(n){r[++t]=[n,n]}),r}function T(n){if(Bn.test(n)){
+for(var t=zn.lastIndex=0;zn.test(n);)++t;n=t}else n=tt(n);return n}function $(n){return Bn.test(n)?n.match(zn)||[]:n.split("")}var F,N=1/0,P=NaN,Z=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]],q=/\b__p\+='';/g,V=/\b(__p\+=)''\+/g,K=/(__e\(.*?\)|\b__t\))\+'';/g,G=/&(?:amp|lt|gt|quot|#39);/g,H=/[&<>"']/g,J=RegExp(G.source),Y=RegExp(H.source),Q=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,nn=/<%=([\s\S]+?)%>/g,tn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,rn=/^\w*$/,en=/^\./,un=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,on=/[\\^$.*+?()[\]{}|]/g,fn=RegExp(on.source),cn=/^\s+|\s+$/g,an=/^\s+/,ln=/\s+$/,sn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,hn=/\{\n\/\* \[wrapped with (.+)\] \*/,pn=/,? & /,_n=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,vn=/\\(\\)?/g,gn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,dn=/\w*$/,yn=/^[-+]0x[0-9a-f]+$/i,bn=/^0b[01]+$/i,xn=/^\[object .+?Constructor\]$/,jn=/^0o[0-7]+$/i,wn=/^(?:0|[1-9]\d*)$/,mn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,An=/($^)/,kn=/['\n\r\u2028\u2029\\]/g,En="[\\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])?)*",On="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+En,Sn="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",In=RegExp("['\u2019]","g"),Rn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),zn=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+Sn+En,"g"),Wn=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)|\\d*(?:(?:1st|2nd|3rd|(?![123])\\dth)\\b)|\\d+",On].join("|"),"g"),Bn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),Ln=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Un="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(" "),Cn={};
+Cn["[object Float32Array]"]=Cn["[object Float64Array]"]=Cn["[object Int8Array]"]=Cn["[object Int16Array]"]=Cn["[object Int32Array]"]=Cn["[object Uint8Array]"]=Cn["[object Uint8ClampedArray]"]=Cn["[object Uint16Array]"]=Cn["[object Uint32Array]"]=true,Cn["[object Arguments]"]=Cn["[object Array]"]=Cn["[object ArrayBuffer]"]=Cn["[object Boolean]"]=Cn["[object DataView]"]=Cn["[object Date]"]=Cn["[object Error]"]=Cn["[object Function]"]=Cn["[object Map]"]=Cn["[object Number]"]=Cn["[object Object]"]=Cn["[object RegExp]"]=Cn["[object Set]"]=Cn["[object String]"]=Cn["[object WeakMap]"]=false;
+var Dn={};Dn["[object Arguments]"]=Dn["[object Array]"]=Dn["[object ArrayBuffer]"]=Dn["[object DataView]"]=Dn["[object Boolean]"]=Dn["[object Date]"]=Dn["[object Float32Array]"]=Dn["[object Float64Array]"]=Dn["[object Int8Array]"]=Dn["[object Int16Array]"]=Dn["[object Int32Array]"]=Dn["[object Map]"]=Dn["[object Number]"]=Dn["[object Object]"]=Dn["[object RegExp]"]=Dn["[object Set]"]=Dn["[object String]"]=Dn["[object Symbol]"]=Dn["[object Uint8Array]"]=Dn["[object Uint8ClampedArray]"]=Dn["[object Uint16Array]"]=Dn["[object Uint32Array]"]=true,
+Dn["[object Error]"]=Dn["[object Function]"]=Dn["[object WeakMap]"]=false;var Mn,Tn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},$n=parseFloat,Fn=parseInt,Nn=typeof global=="object"&&global&&global.Object===Object&&global,Pn=typeof self=="object"&&self&&self.Object===Object&&self,Zn=Nn||Pn||Function("return this")(),qn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Vn=qn&&typeof module=="object"&&module&&!module.nodeType&&module,Kn=Vn&&Vn.exports===qn,Gn=Kn&&Nn.process;
+n:{try{Mn=Gn&&Gn.binding&&Gn.binding("util");break n}catch(n){}Mn=void 0}var Hn=Mn&&Mn.isArrayBuffer,Jn=Mn&&Mn.isDate,Yn=Mn&&Mn.isMap,Qn=Mn&&Mn.isRegExp,Xn=Mn&&Mn.isSet,nt=Mn&&Mn.isTypedArray,tt=j("length"),rt=w({"\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"}),et=w({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}),ut=w({"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"}),it=function w(En){function On(n){if(xu(n)&&!af(n)&&!(n instanceof Mn)){if(n instanceof zn)return n;if(ci.call(n,"__wrapped__"))return Pe(n)}return new zn(n)}function Sn(){}function zn(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=F}function Mn(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,
+this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}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 Nn(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 Pn(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 qn(n){var t=-1,r=null==n?0:n.length;for(this.__data__=new Pn;++t<r;)this.add(n[t])}function Vn(n){
+this.size=(this.__data__=new Nn(n)).size}function Gn(n,t){var r,e=af(n),u=!e&&cf(n),i=!e&&!u&&sf(n),o=!e&&!u&&!i&&gf(n),u=(e=e||u||i||o)?E(n.length,ri):[],f=u.length;for(r in n)!t&&!ci.call(n,r)||e&&("length"==r||i&&("offset"==r||"parent"==r)||o&&("buffer"==r||"byteLength"==r||"byteOffset"==r)||Re(r,f))||u.push(r);return u}function tt(n){var t=n.length;return t?n[cr(0,t-1)]:F}function ot(n,t){return Te(Mr(n),gt(t,0,n.length))}function ft(n){return Te(Mr(n))}function ct(n,t,r){(r===F||hu(n[t],r))&&(r!==F||t in n)||_t(n,t,r);
+}function at(n,t,r){var e=n[t];ci.call(n,t)&&hu(e,r)&&(r!==F||t in n)||_t(n,t,r)}function lt(n,t){for(var r=n.length;r--;)if(hu(n[r][0],t))return r;return-1}function st(n,t,r,e){return oo(n,function(n,u,i){t(e,n,r(n),i)}),e}function ht(n,t){return n&&Tr(t,Lu(t),n)}function pt(n,t){return n&&Tr(t,Uu(t),n)}function _t(n,t,r){"__proto__"==t&&Ei?Ei(n,t,{configurable:true,enumerable:true,value:r,writable:true}):n[t]=r}function vt(n,t){for(var r=-1,e=t.length,u=Hu(e),i=null==n;++r<e;)u[r]=i?F:Wu(n,t[r]);return u;
+}function gt(n,t,r){return n===n&&(r!==F&&(n=n<=r?n:r),t!==F&&(n=n>=t?n:t)),n}function dt(n,t,r,e,i,o){var f,c=1&t,a=2&t,l=4&t;if(r&&(f=i?r(n,e,i,o):r(n)),f!==F)return f;if(!bu(n))return n;if(e=af(n)){if(f=Ee(n),!c)return Mr(n,f)}else{var s=yo(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(sf(n))return Wr(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Oe(n),!c)return a?Fr(n,pt(f,n)):$r(n,ht(f,n))}else{if(!Dn[s])return i?n:{};f=Se(n,s,dt,c)}}if(o||(o=new Vn),
+i=o.get(n))return i;o.set(n,f);var a=l?a?ye:de:a?Uu:Lu,p=e?F:a(n);return u(p||n,function(e,u){p&&(u=e,e=n[u]),at(f,u,dt(e,t,r,u,n,o))}),f}function yt(n){var t=Lu(n);return function(r){return bt(r,n,t)}}function bt(n,t,r){var e=r.length;if(null==n)return!e;for(n=ni(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===F&&!(u in n)||!i(o))return false}return true}function xt(n,t,r){if(typeof n!="function")throw new ei("Expected a function");return jo(function(){n.apply(F,r)},t)}function jt(n,t,r,e){var u=-1,i=c,o=true,f=n.length,s=[],h=t.length;
+if(!f)return s;r&&(t=l(t,S(r))),e?(i=a,o=false):200<=t.length&&(i=R,o=false,t=new qn(t));n:for(;++u<f;){var p=n[u],_=null==r?p:r(p),p=e||0!==p?p:0;if(o&&_===_){for(var v=h;v--;)if(t[v]===_)continue n;s.push(p)}else i(t,_,e)||s.push(p)}return s}function wt(n,t){var r=true;return oo(n,function(n,e,u){return r=!!t(n,e,u)}),r}function mt(n,t,r){for(var e=-1,u=n.length;++e<u;){var i=n[e],o=t(i);if(null!=o&&(f===F?o===o&&!Au(o):r(o,f)))var f=o,c=i}return c}function At(n,t){var r=[];return oo(n,function(n,e,u){
+t(n,e,u)&&r.push(n)}),r}function kt(n,t,r,e,u){var i=-1,o=n.length;for(r||(r=Ie),u||(u=[]);++i<o;){var f=n[i];0<t&&r(f)?1<t?kt(f,t-1,r,e,u):s(u,f):e||(u[u.length]=f)}return u}function Et(n,t){return n&&co(n,t,Lu)}function Ot(n,t){return n&&ao(n,t,Lu)}function St(n,t){return f(t,function(t){return gu(n[t])})}function It(n,t){t=Rr(t,n);for(var r=0,e=t.length;null!=n&&r<e;)n=n[$e(t[r++])];return r&&r==e?n:F}function Rt(n,t,r){return t=t(n),af(n)?t:s(t,r(n))}function zt(n){if(null==n)n=n===F?"[object Undefined]":"[object Null]";else if(ki&&ki in ni(n)){
+var t=ci.call(n,ki),r=n[ki];try{n[ki]=F;var e=true}catch(n){}var u=si.call(n);e&&(t?n[ki]=r:delete n[ki]),n=u}else n=si.call(n);return n}function Wt(n,t){return n>t}function Bt(n,t){return null!=n&&ci.call(n,t)}function Lt(n,t){return null!=n&&t in ni(n)}function Ut(n,t,r){for(var e=r?a:c,u=n[0].length,i=n.length,o=i,f=Hu(i),s=1/0,h=[];o--;){var p=n[o];o&&t&&(p=l(p,S(t))),s=Mi(p.length,s),f[o]=!r&&(t||120<=u&&120<=p.length)?new qn(o&&p):F}var p=n[0],_=-1,v=f[0];n:for(;++_<u&&h.length<s;){var g=p[_],d=t?t(g):g,g=r||0!==g?g:0;
+if(v?!R(v,d):!e(h,d,r)){for(o=i;--o;){var y=f[o];if(y?!R(y,d):!e(n[o],d,r))continue n}v&&v.push(d),h.push(g)}}return h}function Ct(n,t,r){var e={};return Et(n,function(n,u,i){t(e,r(n),u,i)}),e}function Dt(n,t,e){return t=Rr(t,n),n=2>t.length?n:It(n,vr(t,0,-1)),t=null==n?n:n[$e(Ge(t))],null==t?F:r(t,n,e)}function Mt(n){return xu(n)&&"[object Arguments]"==zt(n)}function Tt(n){return xu(n)&&"[object ArrayBuffer]"==zt(n)}function $t(n){return xu(n)&&"[object Date]"==zt(n)}function Ft(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!xu(n)&&!xu(t))t=n!==n&&t!==t;else n:{
+var i=af(n),o=af(t),f=i?"[object Array]":yo(n),c=o?"[object Array]":yo(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)&&sf(n)){if(!sf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Vn),t=i||gf(n)?_e(n,t,r,e,Ft,u):ve(n,t,f,r,e,Ft,u);else{if(!(1&r)&&(i=a&&ci.call(n,"__wrapped__"),f=o&&ci.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Vn),t=Ft(n,t,r,e,u);break n}if(c)t:if(u||(u=new Vn),
+i=1&r,f=de(n),o=f.length,c=de(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ci.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(_===F?h!==p&&!Ft(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 Nt(n){return xu(n)&&"[object Map]"==yo(n)}function Pt(n,t,r,e){var u=r.length,i=u,o=!e;if(null==n)return!i;for(n=ni(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===F&&!(c in n))return false}else{if(f=new Vn,e)var s=e(a,l,c,n,t,f);if(s===F?!Ft(l,a,3,e,f):!s)return false}}return true}function Zt(n){return!(!bu(n)||li&&li in n)&&(gu(n)?_i:xn).test(Fe(n))}function qt(n){
+return xu(n)&&"[object RegExp]"==zt(n)}function Vt(n){return xu(n)&&"[object Set]"==yo(n)}function Kt(n){return xu(n)&&yu(n.length)&&!!Cn[zt(n)]}function Gt(n){return typeof n=="function"?n:null==n?Nu:typeof n=="object"?af(n)?Xt(n[0],n[1]):Qt(n):Vu(n)}function Ht(n){if(!Le(n))return Ci(n);var t,r=[];for(t in ni(n))ci.call(n,t)&&"constructor"!=t&&r.push(t);return r}function Jt(n,t){return n<t}function Yt(n,t){var r=-1,e=pu(n)?Hu(n.length):[];return oo(n,function(n,u,i){e[++r]=t(n,u,i)}),e}function Qt(n){
+var t=me(n);return 1==t.length&&t[0][2]?Ue(t[0][0],t[0][1]):function(r){return r===n||Pt(r,n,t)}}function Xt(n,t){return We(n)&&t===t&&!bu(t)?Ue($e(n),t):function(r){var e=Wu(r,n);return e===F&&e===t?Bu(r,n):Ft(t,e,3)}}function nr(n,t,r,e,u){n!==t&&co(t,function(i,o){if(bu(i)){u||(u=new Vn);var f=u,c=n[o],a=t[o],l=f.get(a);if(l)ct(n,o,l);else{var l=e?e(c,a,o+"",n,t,f):F,s=l===F;if(s){var h=af(a),p=!h&&sf(a),_=!h&&!p&&gf(a),l=a;h||p||_?af(c)?l=c:_u(c)?l=Mr(c):p?(s=false,l=Wr(a,true)):_?(s=false,l=Lr(a,true)):l=[]:wu(a)||cf(a)?(l=c,
+cf(c)?l=Ru(c):(!bu(c)||r&&gu(c))&&(l=Oe(a))):s=false}s&&(f.set(a,l),nr(l,a,r,e,f),f.delete(a)),ct(n,o,l)}}else f=e?e(n[o],i,o+"",n,t,u):F,f===F&&(f=i),ct(n,o,f)},Uu)}function tr(n,t){var r=n.length;if(r)return t+=0>t?r:0,Re(t,r)?n[t]:F}function rr(n,t,r){var e=-1;return t=l(t.length?t:[Nu],S(je())),n=Yt(n,function(n){return{a:l(t,function(t){return t(n)}),b:++e,c:n}}),A(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=Ur(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 er(n,t){return ur(n,t,function(t,r){return Bu(n,r)})}function ur(n,t,r){for(var e=-1,u=t.length,i={};++e<u;){var o=t[e],f=It(n,o);r(f,o)&&pr(i,Rr(o,n),f)}return i}function ir(n){return function(t){return It(t,n)}}function or(n,t,r,e){var u=e?y:d,i=-1,o=t.length,f=n;for(n===t&&(t=Mr(t)),r&&(f=l(n,S(r)));++i<o;)for(var c=0,a=t[i],a=r?r(a):a;-1<(c=u(f,a,c,e));)f!==n&&wi.call(f,c,1),wi.call(n,c,1);return n}function fr(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;Re(u)?wi.call(n,u,1):mr(n,u)}}}function cr(n,t){return n+zi(Fi()*(t-n+1))}function ar(n,t){var r="";if(!n||1>t||9007199254740991<t)return r;do t%2&&(r+=n),(t=zi(t/2))&&(n+=n);while(t);return r}function lr(n,t){return wo(Ce(n,t,Nu),n+"")}function sr(n){return tt(Du(n))}function hr(n,t){var r=Du(n);return Te(r,gt(t,0,r.length))}function pr(n,t,r,e){if(!bu(n))return n;t=Rr(t,n);for(var u=-1,i=t.length,o=i-1,f=n;null!=f&&++u<i;){var c=$e(t[u]),a=r;if(u!=o){var l=f[c],a=e?e(l,c,f):F;
+a===F&&(a=bu(l)?l:Re(t[u+1])?[]:{})}at(f,c,a),f=f[c]}return n}function _r(n){return Te(Du(n))}function vr(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=Hu(u);++e<u;)r[e]=n[e+t];return r}function gr(n,t){var r;return oo(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function dr(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&&!Au(o)&&(r?o<=t:o<t)?e=i+1:u=i}return u}return yr(n,t,Nu,r);
+}function yr(n,t,r,e){t=r(t);for(var u=0,i=null==n?0:n.length,o=t!==t,f=null===t,c=Au(t),a=t===F;u<i;){var l=zi((u+i)/2),s=r(n[l]),h=s!==F,p=null===s,_=s===s,v=Au(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 Mi(i,4294967294)}function br(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||!hu(f,c)){var c=f;i[u++]=0===o?0:o}}return i}function xr(n){return typeof n=="number"?n:Au(n)?P:+n}function jr(n){if(typeof n=="string")return n;
+if(af(n))return l(n,jr)+"";if(Au(n))return uo?uo.call(n):"";var t=n+"";return"0"==t&&1/n==-N?"-0":t}function wr(n,t,r){var e=-1,u=c,i=n.length,o=true,f=[],l=f;if(r)o=false,u=a;else if(200<=i){if(u=t?null:po(n))return D(u);o=false,u=R,l=new qn}else l=t?[]:f;n:for(;++e<i;){var s=n[e],h=t?t(s):s,s=r||0!==s?s:0;if(o&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue n;t&&l.push(h),f.push(s)}else u(l,h,r)||(l!==f&&l.push(h),f.push(s))}return f}function mr(n,t){return t=Rr(t,n),n=2>t.length?n:It(n,vr(t,0,-1)),
+null==n||delete n[$e(Ge(t))]}function Ar(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?vr(n,e?0:i,e?i+1:u):vr(n,e?i+1:0,e?u:i)}function kr(n,t){var r=n;return r instanceof Mn&&(r=r.value()),h(t,function(n,t){return t.func.apply(t.thisArg,s([n],t.args))},r)}function Er(n,t,r){var e=n.length;if(2>e)return e?wr(n[0]):[];for(var u=-1,i=Hu(e);++u<e;)for(var o=n[u],f=-1;++f<e;)f!=u&&(i[u]=jt(i[u]||o,n[f],t,r));return wr(kt(i,1),t,r)}function Or(n,t,r){for(var e=-1,u=n.length,i=t.length,o={};++e<u;)r(o,n[e],e<i?t[e]:F);
+return o}function Sr(n){return _u(n)?n:[]}function Ir(n){return typeof n=="function"?n:Nu}function Rr(n,t){return af(n)?n:We(n,t)?[n]:mo(zu(n))}function zr(n,t,r){var e=n.length;return r=r===F?e:r,!t&&r>=e?n:vr(n,t,r)}function Wr(n,t){if(t)return n.slice();var r=n.length,r=yi?yi(r):new n.constructor(r);return n.copy(r),r}function Br(n){var t=new n.constructor(n.byteLength);return new di(t).set(new di(n)),t}function Lr(n,t){return new n.constructor(t?Br(n.buffer):n.buffer,n.byteOffset,n.length)}function Ur(n,t){
+if(n!==t){var r=n!==F,e=null===n,u=n===n,i=Au(n),o=t!==F,f=null===t,c=t===t,a=Au(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 Cr(n,t,r,e){var u=-1,i=n.length,o=r.length,f=-1,c=t.length,a=Di(i-o,0),l=Hu(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 Dr(n,t,r,e){var u=-1,i=n.length,o=-1,f=r.length,c=-1,a=t.length,l=Di(i-f,0),s=Hu(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 Mr(n,t){var r=-1,e=n.length;for(t||(t=Hu(e));++r<e;)t[r]=n[r];return t}function Tr(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):F;c===F&&(c=n[f]),u?_t(r,f,c):at(r,f,c)}return r}function $r(n,t){return Tr(n,vo(n),t)}function Fr(n,t){return Tr(n,go(n),t)}function Nr(n,t){return function(r,u){var i=af(r)?e:st,o=t?t():{};return i(r,n,je(u,2),o);
+}}function Pr(n){return lr(function(t,r){var e=-1,u=r.length,i=1<u?r[u-1]:F,o=2<u?r[2]:F,i=3<n.length&&typeof i=="function"?(u--,i):F;for(o&&ze(r[0],r[1],o)&&(i=3>u?F:i,u=1),t=ni(t);++e<u;)(o=r[e])&&n(t,o,e,i);return t})}function Zr(n,t){return function(r,e){if(null==r)return r;if(!pu(r))return n(r,e);for(var u=r.length,i=t?u:-1,o=ni(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function qr(n){return function(t,r,e){var u=-1,i=ni(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 Vr(n,t,r){function e(){return(this&&this!==Zn&&this instanceof e?i:n).apply(u?r:this,arguments)}var u=1&t,i=Hr(n);return e}function Kr(n){return function(t){t=zu(t);var r=Bn.test(t)?$(t):F,e=r?r[0]:t.charAt(0);return t=r?zr(r,1).join(""):t.slice(1),e[n]()+t}}function Gr(n){return function(t){return h($u(Tu(t).replace(In,"")),n,"")}}function Hr(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=io(n.prototype),t=n.apply(r,t);return bu(t)?t:r}}function Jr(n,t,e){function u(){for(var o=arguments.length,f=Hu(o),c=o,a=xe(u);c--;)f[c]=arguments[c];return c=3>o&&f[0]!==a&&f[o-1]!==a?[]:C(f,a),o-=c.length,o<e?fe(n,t,Xr,u.placeholder,F,f,c,F,F,e-o):r(this&&this!==Zn&&this instanceof u?i:n,this,f);
+}var i=Hr(n);return u}function Yr(n){return function(t,r,e){var u=ni(t);if(!pu(t)){var i=je(r,3);t=Lu(t),r=function(n){return i(u[n],n,u)}}return r=n(t,r,e),-1<r?u[i?t[r]:r]:F}}function Qr(n){return ge(function(t){var r=t.length,e=r,u=zn.prototype.thru;for(n&&t.reverse();e--;){var i=t[e];if(typeof i!="function")throw new ei("Expected a function");if(u&&!o&&"wrapper"==be(i))var o=new zn([],true)}for(e=o?e:r;++e<r;)var i=t[e],u=be(i),f="wrapper"==u?_o(i):F,o=f&&Be(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?o[be(f[0])].apply(o,f[3]):1==i.length&&Be(i)?o[u]():o.thru(i);
+return function(){var n=arguments,e=n[0];if(o&&1==n.length&&af(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 Xr(n,t,r,e,u,i,o,f,c,a){function l(){for(var d=arguments.length,y=Hu(d),b=d;b--;)y[b]=arguments[b];if(_){var x,j=xe(l),b=y.length;for(x=0;b--;)y[b]===j&&++x}if(e&&(y=Cr(y,e,u,_)),i&&(y=Dr(y,i,o,_)),d-=x,_&&d<a)return j=C(y,j),fe(n,t,Xr,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=Mi(f.length,x),m=Mr(y);w--;){
+var A=f[w];y[w]=Re(A,x)?m[A]:F}}else v&&1<d&&y.reverse();return s&&c<d&&(y.length=c),this&&this!==Zn&&this instanceof l&&(b=g||Hr(b)),b.apply(j,y)}var s=128&t,h=1&t,p=2&t,_=24&t,v=512&t,g=p?F:Hr(n);return l}function ne(n,t){return function(r,e){return Ct(r,n,t(e))}}function te(n,t){return function(r,e){var u;if(r===F&&e===F)return t;if(r!==F&&(u=r),e!==F){if(u===F)return e;typeof r=="string"||typeof e=="string"?(r=jr(r),e=jr(e)):(r=xr(r),e=xr(e)),u=n(r,e)}return u}}function re(n){return ge(function(t){
+return t=l(t,S(je())),lr(function(e){var u=this;return n(t,function(n){return r(n,u,e)})})})}function ee(n,t){t=t===F?" ":jr(t);var r=t.length;return 2>r?r?ar(t,n):t:(r=ar(t,Ri(n/T(t))),Bn.test(t)?zr($(r),0,n).join(""):r.slice(0,n))}function ue(n,t,e,u){function i(){for(var t=-1,c=arguments.length,a=-1,l=u.length,s=Hu(l+c),h=this&&this!==Zn&&this instanceof i?f:n;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++t];return r(h,o?e:this,s)}var o=1&t,f=Hr(n);return i}function ie(n){return function(t,r,e){
+e&&typeof e!="number"&&ze(t,r,e)&&(r=e=F),t=Eu(t),r===F?(r=t,t=0):r=Eu(r),e=e===F?t<r?1:-1:Eu(e);var u=-1;r=Di(Ri((r-t)/(e||1)),0);for(var i=Hu(r);r--;)i[n?r:++u]=t,t+=e;return i}}function oe(n){return function(t,r){return typeof t=="string"&&typeof r=="string"||(t=Iu(t),r=Iu(r)),n(t,r)}}function fe(n,t,r,e,u,i,o,f,c,a){var l=8&t,s=l?o:F;o=l?F:o;var h=l?i:F;return i=l?F: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(F,u),Be(n)&&xo(r,u),r.placeholder=e,De(r,n,t)}function ce(n){
+var t=Xu[n];return function(n,r){if(n=Iu(n),r=null==r?0:Mi(Ou(r),292)){var e=(zu(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(zu(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function ae(n){return function(t){var r=yo(t);return"[object Map]"==r?L(t):"[object Set]"==r?M(t):O(t,n(t))}}function le(n,t,r,e,u,i,o,f){var c=2&t;if(!c&&typeof n!="function")throw new ei("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=F),o=o===F?o:Di(Ou(o),0),f=f===F?f:Ou(f),a-=u?u.length:0,64&t){
+var l=e,s=u;e=u=F}var h=c?F:_o(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?Cr(e,r,h[4]):r,i[4]=e?C(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Dr(e,r,h[6]):r,i[6]=e?C(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Mi(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]===F?c?0:n.length:Di(i[9]-a,0),!f&&24&t&&(t&=-25),De((h?lo:xo)(t&&1!=t?8==t||16==t?Jr(n,t,f):32!=t&&33!=t||u.length?Xr.apply(F,i):ue(n,t,r,e):Vr(n,t,r),i),n,t)}function se(n,t,r,e){return n===F||hu(n,ii[r])&&!ci.call(e,r)?t:n}function he(n,t,r,e,u,i){return bu(n)&&bu(t)&&(i.set(t,n),nr(n,t,F,he,i),i.delete(t)),n}function pe(n){return wu(n)?F:n}function _e(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 qn:F;
+for(i.set(n,t),i.set(t,n);++c<f;){var s=n[c],h=t[c];if(e)var p=o?e(h,s,c,t,n,i):e(s,h,c,n,t,i);if(p!==F){if(p)continue;a=false;break}if(l){if(!_(t,function(n,t){if(!R(l,t)&&(s===n||u(s,n,r,e,i)))return l.push(t)})){a=false;break}}else if(s!==h&&!u(s,h,r,e,i)){a=false;break}}return i.delete(n),i.delete(t),a}function ve(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 di(n),new di(t)))break;
+return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return hu(+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=L;case"[object Set]":if(f||(f=D),n.size!=t.size&&!(1&e))break;return(r=o.get(n))?r==t:(e|=2,o.set(n,t),t=_e(f(n),f(t),e,u,i,o),o.delete(n),t);case"[object Symbol]":if(eo)return eo.call(n)==eo.call(t)}return false}function ge(n){return wo(Ce(n,F,Ve),n+"")}function de(n){
+return Rt(n,Lu,vo)}function ye(n){return Rt(n,Uu,go)}function be(n){for(var t=n.name+"",r=Ji[t],e=ci.call(Ji,t)?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function xe(n){return(ci.call(On,"placeholder")?On:n).placeholder}function je(){var n=On.iteratee||Pu,n=n===Pu?Gt:n;return arguments.length?n(arguments[0],arguments[1]):n}function we(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 me(n){for(var t=Lu(n),r=t.length;r--;){var e=t[r],u=n[e];t[r]=[e,u,u===u&&!bu(u)]}return t}function Ae(n,t){var r=null==n?F:n[t];return Zt(r)?r:F}function ke(n,t,r){t=Rr(t,n);for(var e=-1,u=t.length,i=false;++e<u;){var o=$e(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&&yu(u)&&Re(o,u)&&(af(n)||cf(n)))}function Ee(n){var t=n.length,r=n.constructor(t);return t&&"string"==typeof n[0]&&ci.call(n,"index")&&(r.index=n.index,r.input=n.input),r}function Oe(n){
+return typeof n.constructor!="function"||Le(n)?{}:io(bi(n))}function Se(r,e,u,i){var o=r.constructor;switch(e){case"[object ArrayBuffer]":return Br(r);case"[object Boolean]":case"[object Date]":return new o(+r);case"[object DataView]":return e=i?Br(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.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 Lr(r,i);case"[object Map]":return e=i?u(L(r),1):L(r),h(e,n,new r.constructor);case"[object Number]":case"[object String]":return new o(r);case"[object RegExp]":return e=new r.constructor(r.source,dn.exec(r)),e.lastIndex=r.lastIndex,e;case"[object Set]":return e=i?u(D(r),1):D(r),h(e,t,new r.constructor);case"[object Symbol]":return eo?ni(eo.call(r)):{}}}function Ie(n){return af(n)||cf(n)||!!(mi&&n&&n[mi])}function Re(n,t){return t=null==t?9007199254740991:t,
+!!t&&(typeof n=="number"||wn.test(n))&&-1<n&&0==n%1&&n<t}function ze(n,t,r){if(!bu(r))return false;var e=typeof t;return!!("number"==e?pu(r)&&Re(t,r.length):"string"==e&&t in r)&&hu(r[t],n)}function We(n,t){if(af(n))return false;var r=typeof n;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=n&&!Au(n))||(rn.test(n)||!tn.test(n)||null!=t&&n in ni(t))}function Be(n){var t=be(n),r=On[t];return typeof r=="function"&&t in Mn.prototype&&(n===r||(t=_o(r),!!t&&n===t[0]))}function Le(n){var t=n&&n.constructor;
+return n===(typeof t=="function"&&t.prototype||ii)}function Ue(n,t){return function(r){return null!=r&&(r[n]===t&&(t!==F||n in ni(r)))}}function Ce(n,t,e){return t=Di(t===F?n.length-1:t,0),function(){for(var u=arguments,i=-1,o=Di(u.length-t,0),f=Hu(o);++i<o;)f[i]=u[t+i];for(i=-1,o=Hu(t+1);++i<t;)o[i]=u[i];return o[t]=e(f),r(n,this,o)}}function De(n,t,r){var e=t+"";t=wo;var u,i=Ne;return u=(u=e.match(hn))?u[1].split(pn):[],r=i(u,r),(i=r.length)&&(u=i-1,r[u]=(1<i?"& ":"")+r[u],r=r.join(2<i?", ":" "),
+e=e.replace(sn,"{\n/* [wrapped with "+r+"] */\n")),t(n,e)}function Me(n){var t=0,r=0;return function(){var e=Ti(),u=16-(e-r);if(r=e,0<u){if(800<=++t)return arguments[0]}else t=0;return n.apply(F,arguments)}}function Te(n,t){var r=-1,e=n.length,u=e-1;for(t=t===F?e:t;++r<t;){var e=cr(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function $e(n){if(typeof n=="string"||Au(n))return n;var t=n+"";return"0"==t&&1/n==-N?"-0":t}function Fe(n){if(null!=n){try{return fi.call(n)}catch(n){}return n+""}return"";
+}function Ne(n,t){return u(Z,function(r){var e="_."+r[0];t&r[1]&&!c(n,e)&&n.push(e)}),n.sort()}function Pe(n){if(n instanceof Mn)return n.clone();var t=new zn(n.__wrapped__,n.__chain__);return t.__actions__=Mr(n.__actions__),t.__index__=n.__index__,t.__values__=n.__values__,t}function Ze(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Ou(r),0>r&&(r=Di(e+r,0)),g(n,je(t,3),r)):-1}function qe(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==F&&(u=Ou(r),u=0>r?Di(e+u,0):Mi(u,e-1)),
+g(n,je(t,3),u,true)}function Ve(n){return(null==n?0:n.length)?kt(n,1):[]}function Ke(n){return n&&n.length?n[0]:F}function Ge(n){var t=null==n?0:n.length;return t?n[t-1]:F}function He(n,t){return n&&n.length&&t&&t.length?or(n,t):n}function Je(n){return null==n?n:Ni.call(n)}function Ye(n){if(!n||!n.length)return[];var t=0;return n=f(n,function(n){if(_u(n))return t=Di(n.length,t),true}),E(t,function(t){return l(n,j(t))})}function Qe(n,t){if(!n||!n.length)return[];var e=Ye(n);return null==t?e:l(e,function(n){
+return r(t,F,n)})}function Xe(n){return n=On(n),n.__chain__=true,n}function nu(n,t){return t(n)}function tu(){return this}function ru(n,t){return(af(n)?u:oo)(n,je(t,3))}function eu(n,t){return(af(n)?i:fo)(n,je(t,3))}function uu(n,t){return(af(n)?l:Yt)(n,je(t,3))}function iu(n,t,r){return t=r?F:t,t=n&&null==t?n.length:t,le(n,128,F,F,F,F,t)}function ou(n,t){var r;if(typeof t!="function")throw new ei("Expected a function");return n=Ou(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=F),
+r}}function fu(n,t,r){return t=r?F:t,n=le(n,8,F,F,F,F,F,t),n.placeholder=fu.placeholder,n}function cu(n,t,r){return t=r?F:t,n=le(n,16,F,F,F,F,F,t),n.placeholder=cu.placeholder,n}function au(n,t,r){function e(t){var r=c,e=a;return c=a=F,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===F||r>=t||0>r||g&&n>=l}function i(){var n=Jo();if(u(n))return o(n);var r,e=jo;r=n-_,n=t-(n-p),r=g?Mi(n,l-r):n,h=e(i,r)}function o(n){return h=F,d&&c?e(n):(c=a=F,s)}function f(){var n=Jo(),r=u(n);if(c=arguments,
+a=this,p=n,r){if(h===F)return _=n=p,h=jo(i,t),v?e(n):s;if(g)return h=jo(i,t),e(p)}return h===F&&(h=jo(i,t)),s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ei("Expected a function");return t=Iu(t)||0,bu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Di(Iu(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==F&&ho(h),_=0,c=p=a=h=F},f.flush=function(){return h===F?s:o(Jo())},f}function lu(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 ei("Expected a function");return r.cache=new(lu.Cache||Pn),r}function su(n){if(typeof n!="function")throw new ei("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 hu(n,t){return n===t||n!==n&&t!==t}function pu(n){return null!=n&&yu(n.length)&&!gu(n);
+}function _u(n){return xu(n)&&pu(n)}function vu(n){if(!xu(n))return false;var t=zt(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!wu(n)}function gu(n){return!!bu(n)&&(n=zt(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function du(n){return typeof n=="number"&&n==Ou(n)}function yu(n){return typeof n=="number"&&-1<n&&0==n%1&&9007199254740991>=n}function bu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t);
+}function xu(n){return null!=n&&typeof n=="object"}function ju(n){return typeof n=="number"||xu(n)&&"[object Number]"==zt(n)}function wu(n){return!(!xu(n)||"[object Object]"!=zt(n))&&(n=bi(n),null===n||(n=ci.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&fi.call(n)==hi))}function mu(n){return typeof n=="string"||!af(n)&&xu(n)&&"[object String]"==zt(n)}function Au(n){return typeof n=="symbol"||xu(n)&&"[object Symbol]"==zt(n)}function ku(n){if(!n)return[];if(pu(n))return mu(n)?$(n):Mr(n);
+if(Ai&&n[Ai]){n=n[Ai]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=yo(n),("[object Map]"==t?L:"[object Set]"==t?D:Du)(n)}function Eu(n){return n?(n=Iu(n),n===N||n===-N?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Ou(n){n=Eu(n);var t=n%1;return n===n?t?n-t:n:0}function Su(n){return n?gt(Ou(n),0,4294967295):0}function Iu(n){if(typeof n=="number")return n;if(Au(n))return P;if(bu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=bu(n)?n+"":n),typeof n!="string")return 0===n?n:+n;
+n=n.replace(cn,"");var t=bn.test(n);return t||jn.test(n)?Fn(n.slice(2),t?2:8):yn.test(n)?P:+n}function Ru(n){return Tr(n,Uu(n))}function zu(n){return null==n?"":jr(n)}function Wu(n,t,r){return n=null==n?F:It(n,t),n===F?r:n}function Bu(n,t){return null!=n&&ke(n,t,Lt)}function Lu(n){return pu(n)?Gn(n):Ht(n)}function Uu(n){if(pu(n))n=Gn(n,true);else if(bu(n)){var t,r=Le(n),e=[];for(t in n)("constructor"!=t||!r&&ci.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in ni(n))t.push(r);n=t}return n}function Cu(n,t){
+if(null==n)return{};var r=l(ye(n),function(n){return[n]});return t=je(t),ur(n,r,function(n,r){return t(n,r[0])})}function Du(n){return null==n?[]:I(n,Lu(n))}function Mu(n){return Nf(zu(n).toLowerCase())}function Tu(n){return(n=zu(n))&&n.replace(mn,rt).replace(Rn,"")}function $u(n,t,r){return n=zu(n),t=r?F:t,t===F?Ln.test(n)?n.match(Wn)||[]:n.match(_n)||[]:n.match(t)||[]}function Fu(n){return function(){return n}}function Nu(n){return n}function Pu(n){return Gt(typeof n=="function"?n:dt(n,1))}function Zu(n,t,r){
+var e=Lu(t),i=St(t,e);null!=r||bu(t)&&(i.length||!e.length)||(r=t,t=n,n=this,i=St(t,Lu(t)));var o=!(bu(r)&&"chain"in r&&!r.chain),f=gu(n);return u(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__=Mr(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,s([this.value()],arguments))})}),n}function qu(){}function Vu(n){return We(n)?j($e(n)):ir(n)}function Ku(){return[]}function Gu(){
+return false}En=null==En?Zn:it.defaults(Zn.Object(),En,it.pick(Zn,Un));var Hu=En.Array,Ju=En.Date,Yu=En.Error,Qu=En.Function,Xu=En.Math,ni=En.Object,ti=En.RegExp,ri=En.String,ei=En.TypeError,ui=Hu.prototype,ii=ni.prototype,oi=En["__core-js_shared__"],fi=Qu.prototype.toString,ci=ii.hasOwnProperty,ai=0,li=function(){var n=/[^.]+$/.exec(oi&&oi.keys&&oi.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),si=ii.toString,hi=fi.call(ni),pi=Zn._,_i=ti("^"+fi.call(ci).replace(on,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),vi=Kn?En.Buffer:F,gi=En.Symbol,di=En.Uint8Array,yi=vi?vi.f:F,bi=U(ni.getPrototypeOf,ni),xi=ni.create,ji=ii.propertyIsEnumerable,wi=ui.splice,mi=gi?gi.isConcatSpreadable:F,Ai=gi?gi.iterator:F,ki=gi?gi.toStringTag:F,Ei=function(){
+try{var n=Ae(ni,"defineProperty");return n({},"",{}),n}catch(n){}}(),Oi=En.clearTimeout!==Zn.clearTimeout&&En.clearTimeout,Si=Ju&&Ju.now!==Zn.Date.now&&Ju.now,Ii=En.setTimeout!==Zn.setTimeout&&En.setTimeout,Ri=Xu.ceil,zi=Xu.floor,Wi=ni.getOwnPropertySymbols,Bi=vi?vi.isBuffer:F,Li=En.isFinite,Ui=ui.join,Ci=U(ni.keys,ni),Di=Xu.max,Mi=Xu.min,Ti=Ju.now,$i=En.parseInt,Fi=Xu.random,Ni=ui.reverse,Pi=Ae(En,"DataView"),Zi=Ae(En,"Map"),qi=Ae(En,"Promise"),Vi=Ae(En,"Set"),Ki=Ae(En,"WeakMap"),Gi=Ae(ni,"create"),Hi=Ki&&new Ki,Ji={},Yi=Fe(Pi),Qi=Fe(Zi),Xi=Fe(qi),no=Fe(Vi),to=Fe(Ki),ro=gi?gi.prototype:F,eo=ro?ro.valueOf:F,uo=ro?ro.toString:F,io=function(){
+function n(){}return function(t){return bu(t)?xi?xi(t):(n.prototype=t,t=new n,n.prototype=F,t):{}}}();On.templateSettings={escape:Q,evaluate:X,interpolate:nn,variable:"",imports:{_:On}},On.prototype=Sn.prototype,On.prototype.constructor=On,zn.prototype=io(Sn.prototype),zn.prototype.constructor=zn,Mn.prototype=io(Sn.prototype),Mn.prototype.constructor=Mn,Tn.prototype.clear=function(){this.__data__=Gi?Gi(null):{},this.size=0},Tn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n],
+this.size-=n?1:0,n},Tn.prototype.get=function(n){var t=this.__data__;return Gi?(n=t[n],"__lodash_hash_undefined__"===n?F:n):ci.call(t,n)?t[n]:F},Tn.prototype.has=function(n){var t=this.__data__;return Gi?t[n]!==F:ci.call(t,n)},Tn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=Gi&&t===F?"__lodash_hash_undefined__":t,this},Nn.prototype.clear=function(){this.__data__=[],this.size=0},Nn.prototype.delete=function(n){var t=this.__data__;return n=lt(t,n),!(0>n)&&(n==t.length-1?t.pop():wi.call(t,n,1),
+--this.size,true)},Nn.prototype.get=function(n){var t=this.__data__;return n=lt(t,n),0>n?F:t[n][1]},Nn.prototype.has=function(n){return-1<lt(this.__data__,n)},Nn.prototype.set=function(n,t){var r=this.__data__,e=lt(r,n);return 0>e?(++this.size,r.push([n,t])):r[e][1]=t,this},Pn.prototype.clear=function(){this.size=0,this.__data__={hash:new Tn,map:new(Zi||Nn),string:new Tn}},Pn.prototype.delete=function(n){return n=we(this,n).delete(n),this.size-=n?1:0,n},Pn.prototype.get=function(n){return we(this,n).get(n);
+},Pn.prototype.has=function(n){return we(this,n).has(n)},Pn.prototype.set=function(n,t){var r=we(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},qn.prototype.add=qn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},qn.prototype.has=function(n){return this.__data__.has(n)},Vn.prototype.clear=function(){this.__data__=new Nn,this.size=0},Vn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Vn.prototype.get=function(n){
+return this.__data__.get(n)},Vn.prototype.has=function(n){return this.__data__.has(n)},Vn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Nn){var e=r.__data__;if(!Zi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Pn(e)}return r.set(n,t),this.size=r.size,this};var oo=Zr(Et),fo=Zr(Ot,true),co=qr(),ao=qr(true),lo=Hi?function(n,t){return Hi.set(n,t),n}:Nu,so=Ei?function(n,t){return Ei(n,"toString",{configurable:true,enumerable:false,value:Fu(t),writable:true})}:Nu,ho=Oi||function(n){
+return Zn.clearTimeout(n)},po=Vi&&1/D(new Vi([,-0]))[1]==N?function(n){return new Vi(n)}:qu,_o=Hi?function(n){return Hi.get(n)}:qu,vo=Wi?function(n){return null==n?[]:(n=ni(n),f(Wi(n),function(t){return ji.call(n,t)}))}:Ku,go=Wi?function(n){for(var t=[];n;)s(t,vo(n)),n=bi(n);return t}:Ku,yo=zt;(Pi&&"[object DataView]"!=yo(new Pi(new ArrayBuffer(1)))||Zi&&"[object Map]"!=yo(new Zi)||qi&&"[object Promise]"!=yo(qi.resolve())||Vi&&"[object Set]"!=yo(new Vi)||Ki&&"[object WeakMap]"!=yo(new Ki))&&(yo=function(n){
+var t=zt(n);if(n=(n="[object Object]"==t?n.constructor:F)?Fe(n):"")switch(n){case Yi:return"[object DataView]";case Qi:return"[object Map]";case Xi:return"[object Promise]";case no:return"[object Set]";case to:return"[object WeakMap]"}return t});var bo=oi?gu:Gu,xo=Me(lo),jo=Ii||function(n,t){return Zn.setTimeout(n,t)},wo=Me(so),mo=function(n){n=lu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return en.test(n)&&t.push(""),n.replace(un,function(n,r,e,u){
+t.push(e?u.replace(vn,"$1"):r||n)}),t}),Ao=lr(function(n,t){return _u(n)?jt(n,kt(t,1,_u,true)):[]}),ko=lr(function(n,t){var r=Ge(t);return _u(r)&&(r=F),_u(n)?jt(n,kt(t,1,_u,true),je(r,2)):[]}),Eo=lr(function(n,t){var r=Ge(t);return _u(r)&&(r=F),_u(n)?jt(n,kt(t,1,_u,true),F,r):[]}),Oo=lr(function(n){var t=l(n,Sr);return t.length&&t[0]===n[0]?Ut(t):[]}),So=lr(function(n){var t=Ge(n),r=l(n,Sr);return t===Ge(r)?t=F:r.pop(),r.length&&r[0]===n[0]?Ut(r,je(t,2)):[]}),Io=lr(function(n){var t=Ge(n),r=l(n,Sr);return(t=typeof t=="function"?t:F)&&r.pop(),
+r.length&&r[0]===n[0]?Ut(r,F,t):[]}),Ro=lr(He),zo=ge(function(n,t){var r=null==n?0:n.length,e=vt(n,t);return fr(n,l(t,function(n){return Re(n,r)?+n:n}).sort(Ur)),e}),Wo=lr(function(n){return wr(kt(n,1,_u,true))}),Bo=lr(function(n){var t=Ge(n);return _u(t)&&(t=F),wr(kt(n,1,_u,true),je(t,2))}),Lo=lr(function(n){var t=Ge(n),t=typeof t=="function"?t:F;return wr(kt(n,1,_u,true),F,t)}),Uo=lr(function(n,t){return _u(n)?jt(n,t):[]}),Co=lr(function(n){return Er(f(n,_u))}),Do=lr(function(n){var t=Ge(n);return _u(t)&&(t=F),
+Er(f(n,_u),je(t,2))}),Mo=lr(function(n){var t=Ge(n),t=typeof t=="function"?t:F;return Er(f(n,_u),F,t)}),To=lr(Ye),$o=lr(function(n){var t=n.length,t=1<t?n[t-1]:F,t=typeof t=="function"?(n.pop(),t):F;return Qe(n,t)}),Fo=ge(function(n){function t(t){return vt(t,n)}var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return!(1<r||this.__actions__.length)&&u instanceof Mn&&Re(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:nu,args:[t],thisArg:F}),new zn(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(F),
+n})):this.thru(t)}),No=Nr(function(n,t,r){ci.call(n,r)?++n[r]:_t(n,r,1)}),Po=Yr(Ze),Zo=Yr(qe),qo=Nr(function(n,t,r){ci.call(n,r)?n[r].push(t):_t(n,r,[t])}),Vo=lr(function(n,t,e){var u=-1,i=typeof t=="function",o=pu(n)?Hu(n.length):[];return oo(n,function(n){o[++u]=i?r(t,n,e):Dt(n,t,e)}),o}),Ko=Nr(function(n,t,r){_t(n,r,t)}),Go=Nr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ho=lr(function(n,t){if(null==n)return[];var r=t.length;return 1<r&&ze(n,t[0],t[1])?t=[]:2<r&&ze(t[0],t[1],t[2])&&(t=[t[0]]),
+rr(n,kt(t,1),[])}),Jo=Si||function(){return Zn.Date.now()},Yo=lr(function(n,t,r){var e=1;if(r.length)var u=C(r,xe(Yo)),e=32|e;return le(n,e,t,r,u)}),Qo=lr(function(n,t,r){var e=3;if(r.length)var u=C(r,xe(Qo)),e=32|e;return le(t,e,n,r,u)}),Xo=lr(function(n,t){return xt(n,1,t)}),nf=lr(function(n,t,r){return xt(n,Iu(t)||0,r)});lu.Cache=Pn;var tf=lr(function(n,t){t=1==t.length&&af(t[0])?l(t[0],S(je())):l(kt(t,1),S(je()));var e=t.length;return lr(function(u){for(var i=-1,o=Mi(u.length,e);++i<o;)u[i]=t[i].call(this,u[i]);
+return r(n,this,u)})}),rf=lr(function(n,t){return le(n,32,F,t,C(t,xe(rf)))}),ef=lr(function(n,t){return le(n,64,F,t,C(t,xe(ef)))}),uf=ge(function(n,t){return le(n,256,F,F,F,t)}),of=oe(Wt),ff=oe(function(n,t){return n>=t}),cf=Mt(function(){return arguments}())?Mt:function(n){return xu(n)&&ci.call(n,"callee")&&!ji.call(n,"callee")},af=Hu.isArray,lf=Hn?S(Hn):Tt,sf=Bi||Gu,hf=Jn?S(Jn):$t,pf=Yn?S(Yn):Nt,_f=Qn?S(Qn):qt,vf=Xn?S(Xn):Vt,gf=nt?S(nt):Kt,df=oe(Jt),yf=oe(function(n,t){return n<=t}),bf=Pr(function(n,t){
+if(Le(t)||pu(t))Tr(t,Lu(t),n);else for(var r in t)ci.call(t,r)&&at(n,r,t[r])}),xf=Pr(function(n,t){Tr(t,Uu(t),n)}),jf=Pr(function(n,t,r,e){Tr(t,Uu(t),n,e)}),wf=Pr(function(n,t,r,e){Tr(t,Lu(t),n,e)}),mf=ge(vt),Af=lr(function(n){return n.push(F,se),r(jf,F,n)}),kf=lr(function(n){return n.push(F,he),r(Rf,F,n)}),Ef=ne(function(n,t,r){n[t]=r},Fu(Nu)),Of=ne(function(n,t,r){ci.call(n,t)?n[t].push(r):n[t]=[r]},je),Sf=lr(Dt),If=Pr(function(n,t,r){nr(n,t,r)}),Rf=Pr(function(n,t,r,e){nr(n,t,r,e)}),zf=ge(function(n,t){
+var r={};if(null==n)return r;var e=false;t=l(t,function(t){return t=Rr(t,n),e||(e=1<t.length),t}),Tr(n,ye(n),r),e&&(r=dt(r,7,pe));for(var u=t.length;u--;)mr(r,t[u]);return r}),Wf=ge(function(n,t){return null==n?{}:er(n,t)}),Bf=ae(Lu),Lf=ae(Uu),Uf=Gr(function(n,t,r){return t=t.toLowerCase(),n+(r?Mu(t):t)}),Cf=Gr(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Df=Gr(function(n,t,r){return n+(r?" ":"")+t.toLowerCase()}),Mf=Kr("toLowerCase"),Tf=Gr(function(n,t,r){return n+(r?"_":"")+t.toLowerCase();
+}),$f=Gr(function(n,t,r){return n+(r?" ":"")+Nf(t)}),Ff=Gr(function(n,t,r){return n+(r?" ":"")+t.toUpperCase()}),Nf=Kr("toUpperCase"),Pf=lr(function(n,t){try{return r(n,F,t)}catch(n){return vu(n)?n:new Yu(n)}}),Zf=ge(function(n,t){return u(t,function(t){t=$e(t),_t(n,t,Yo(n[t],n))}),n}),qf=Qr(),Vf=Qr(true),Kf=lr(function(n,t){return function(r){return Dt(r,n,t)}}),Gf=lr(function(n,t){return function(r){return Dt(n,r,t)}}),Hf=re(l),Jf=re(o),Yf=re(_),Qf=ie(),Xf=ie(true),nc=te(function(n,t){return n+t},0),tc=ce("ceil"),rc=te(function(n,t){
+return n/t},1),ec=ce("floor"),uc=te(function(n,t){return n*t},1),ic=ce("round"),oc=te(function(n,t){return n-t},0);return On.after=function(n,t){if(typeof t!="function")throw new ei("Expected a function");return n=Ou(n),function(){if(1>--n)return t.apply(this,arguments)}},On.ary=iu,On.assign=bf,On.assignIn=xf,On.assignInWith=jf,On.assignWith=wf,On.at=mf,On.before=ou,On.bind=Yo,On.bindAll=Zf,On.bindKey=Qo,On.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return af(n)?n:[n]},
+On.chain=Xe,On.chunk=function(n,t,r){if(t=(r?ze(n,t,r):t===F)?1:Di(Ou(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Hu(Ri(r/t));e<r;)i[u++]=vr(n,e,e+=t);return i},On.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},On.concat=function(){var n=arguments.length;if(!n)return[];for(var t=Hu(n-1),r=arguments[0];n--;)t[n-1]=arguments[n];return s(af(r)?Mr(r):[r],kt(t,1))},On.cond=function(n){var t=null==n?0:n.length,e=je();return n=t?l(n,function(n){
+if("function"!=typeof n[1])throw new ei("Expected a function");return[e(n[0]),n[1]]}):[],lr(function(e){for(var u=-1;++u<t;){var i=n[u];if(r(i[0],this,e))return r(i[1],this,e)}})},On.conforms=function(n){return yt(dt(n,1))},On.constant=Fu,On.countBy=No,On.create=function(n,t){var r=io(n);return null==t?r:ht(r,t)},On.curry=fu,On.curryRight=cu,On.debounce=au,On.defaults=Af,On.defaultsDeep=kf,On.defer=Xo,On.delay=nf,On.difference=Ao,On.differenceBy=ko,On.differenceWith=Eo,On.drop=function(n,t,r){var e=null==n?0:n.length;
+return e?(t=r||t===F?1:Ou(t),vr(n,0>t?0:t,e)):[]},On.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===F?1:Ou(t),t=e-t,vr(n,0,0>t?0:t)):[]},On.dropRightWhile=function(n,t){return n&&n.length?Ar(n,je(t,3),true,true):[]},On.dropWhile=function(n,t){return n&&n.length?Ar(n,je(t,3),true):[]},On.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&ze(n,t,r)&&(r=0,e=u),u=n.length,r=Ou(r),0>r&&(r=-r>u?0:u+r),e=e===F||e>u?u:Ou(e),0>e&&(e+=u),e=r>e?0:Su(e);r<e;)n[r++]=t;
+return n},On.filter=function(n,t){return(af(n)?f:At)(n,je(t,3))},On.flatMap=function(n,t){return kt(uu(n,t),1)},On.flatMapDeep=function(n,t){return kt(uu(n,t),N)},On.flatMapDepth=function(n,t,r){return r=r===F?1:Ou(r),kt(uu(n,t),r)},On.flatten=Ve,On.flattenDeep=function(n){return(null==n?0:n.length)?kt(n,N):[]},On.flattenDepth=function(n,t){return null!=n&&n.length?(t=t===F?1:Ou(t),kt(n,t)):[]},On.flip=function(n){return le(n,512)},On.flow=qf,On.flowRight=Vf,On.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},On.functions=function(n){return null==n?[]:St(n,Lu(n))},On.functionsIn=function(n){return null==n?[]:St(n,Uu(n))},On.groupBy=qo,On.initial=function(n){return(null==n?0:n.length)?vr(n,0,-1):[]},On.intersection=Oo,On.intersectionBy=So,On.intersectionWith=Io,On.invert=Ef,On.invertBy=Of,On.invokeMap=Vo,On.iteratee=Pu,On.keyBy=Ko,On.keys=Lu,On.keysIn=Uu,On.map=uu,On.mapKeys=function(n,t){var r={};return t=je(t,3),Et(n,function(n,e,u){_t(r,t(n,e,u),n)}),r},On.mapValues=function(n,t){
+var r={};return t=je(t,3),Et(n,function(n,e,u){_t(r,e,t(n,e,u))}),r},On.matches=function(n){return Qt(dt(n,1))},On.matchesProperty=function(n,t){return Xt(n,dt(t,1))},On.memoize=lu,On.merge=If,On.mergeWith=Rf,On.method=Kf,On.methodOf=Gf,On.mixin=Zu,On.negate=su,On.nthArg=function(n){return n=Ou(n),lr(function(t){return tr(t,n)})},On.omit=zf,On.omitBy=function(n,t){return Cu(n,su(je(t)))},On.once=function(n){return ou(2,n)},On.orderBy=function(n,t,r,e){return null==n?[]:(af(t)||(t=null==t?[]:[t]),
+r=e?F:r,af(r)||(r=null==r?[]:[r]),rr(n,t,r))},On.over=Hf,On.overArgs=tf,On.overEvery=Jf,On.overSome=Yf,On.partial=rf,On.partialRight=ef,On.partition=Go,On.pick=Wf,On.pickBy=Cu,On.property=Vu,On.propertyOf=function(n){return function(t){return null==n?F:It(n,t)}},On.pull=Ro,On.pullAll=He,On.pullAllBy=function(n,t,r){return n&&n.length&&t&&t.length?or(n,t,je(r,2)):n},On.pullAllWith=function(n,t,r){return n&&n.length&&t&&t.length?or(n,t,F,r):n},On.pullAt=zo,On.range=Qf,On.rangeRight=Xf,On.rearg=uf,On.reject=function(n,t){
+return(af(n)?f:At)(n,su(je(t,3)))},On.remove=function(n,t){var r=[];if(!n||!n.length)return r;var e=-1,u=[],i=n.length;for(t=je(t,3);++e<i;){var o=n[e];t(o,e,n)&&(r.push(o),u.push(e))}return fr(n,u),r},On.rest=function(n,t){if(typeof n!="function")throw new ei("Expected a function");return t=t===F?t:Ou(t),lr(n,t)},On.reverse=Je,On.sampleSize=function(n,t,r){return t=(r?ze(n,t,r):t===F)?1:Ou(t),(af(n)?ot:hr)(n,t)},On.set=function(n,t,r){return null==n?n:pr(n,t,r)},On.setWith=function(n,t,r,e){return e=typeof e=="function"?e:F,
+null==n?n:pr(n,t,r,e)},On.shuffle=function(n){return(af(n)?ft:_r)(n)},On.slice=function(n,t,r){var e=null==n?0:n.length;return e?(r&&typeof r!="number"&&ze(n,t,r)?(t=0,r=e):(t=null==t?0:Ou(t),r=r===F?e:Ou(r)),vr(n,t,r)):[]},On.sortBy=Ho,On.sortedUniq=function(n){return n&&n.length?br(n):[]},On.sortedUniqBy=function(n,t){return n&&n.length?br(n,je(t,2)):[]},On.split=function(n,t,r){return r&&typeof r!="number"&&ze(n,t,r)&&(t=r=F),r=r===F?4294967295:r>>>0,r?(n=zu(n))&&(typeof t=="string"||null!=t&&!_f(t))&&(t=jr(t),
+!t&&Bn.test(n))?zr($(n),0,r):n.split(t,r):[]},On.spread=function(n,t){if(typeof n!="function")throw new ei("Expected a function");return t=null==t?0:Di(Ou(t),0),lr(function(e){var u=e[t];return e=zr(e,0,t),u&&s(e,u),r(n,this,e)})},On.tail=function(n){var t=null==n?0:n.length;return t?vr(n,1,t):[]},On.take=function(n,t,r){return n&&n.length?(t=r||t===F?1:Ou(t),vr(n,0,0>t?0:t)):[]},On.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===F?1:Ou(t),t=e-t,vr(n,0>t?0:t,e)):[]},On.takeRightWhile=function(n,t){
+return n&&n.length?Ar(n,je(t,3),false,true):[]},On.takeWhile=function(n,t){return n&&n.length?Ar(n,je(t,3)):[]},On.tap=function(n,t){return t(n),n},On.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ei("Expected a function");return bu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),au(n,t,{leading:e,maxWait:t,trailing:u})},On.thru=nu,On.toArray=ku,On.toPairs=Bf,On.toPairsIn=Lf,On.toPath=function(n){return af(n)?l(n,$e):Au(n)?[n]:Mr(mo(zu(n)))},On.toPlainObject=Ru,
+On.transform=function(n,t,r){var e=af(n),i=e||sf(n)||gf(n);if(t=je(t,4),null==r){var o=n&&n.constructor;r=i?e?new o:[]:bu(n)&&gu(o)?io(bi(n)):{}}return(i?u:Et)(n,function(n,e,u){return t(r,n,e,u)}),r},On.unary=function(n){return iu(n,1)},On.union=Wo,On.unionBy=Bo,On.unionWith=Lo,On.uniq=function(n){return n&&n.length?wr(n):[]},On.uniqBy=function(n,t){return n&&n.length?wr(n,je(t,2)):[]},On.uniqWith=function(n,t){return t=typeof t=="function"?t:F,n&&n.length?wr(n,F,t):[]},On.unset=function(n,t){return null==n||mr(n,t);
+},On.unzip=Ye,On.unzipWith=Qe,On.update=function(n,t,r){return null==n?n:pr(n,t,Ir(r)(It(n,t)),void 0)},On.updateWith=function(n,t,r,e){return e=typeof e=="function"?e:F,null!=n&&(n=pr(n,t,Ir(r)(It(n,t)),e)),n},On.values=Du,On.valuesIn=function(n){return null==n?[]:I(n,Uu(n))},On.without=Uo,On.words=$u,On.wrap=function(n,t){return rf(Ir(t),n)},On.xor=Co,On.xorBy=Do,On.xorWith=Mo,On.zip=To,On.zipObject=function(n,t){return Or(n||[],t||[],at)},On.zipObjectDeep=function(n,t){return Or(n||[],t||[],pr);
+},On.zipWith=$o,On.entries=Bf,On.entriesIn=Lf,On.extend=xf,On.extendWith=jf,Zu(On,On),On.add=nc,On.attempt=Pf,On.camelCase=Uf,On.capitalize=Mu,On.ceil=tc,On.clamp=function(n,t,r){return r===F&&(r=t,t=F),r!==F&&(r=Iu(r),r=r===r?r:0),t!==F&&(t=Iu(t),t=t===t?t:0),gt(Iu(n),t,r)},On.clone=function(n){return dt(n,4)},On.cloneDeep=function(n){return dt(n,5)},On.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:F,dt(n,5,t)},On.cloneWith=function(n,t){return t=typeof t=="function"?t:F,dt(n,4,t)},
+On.conformsTo=function(n,t){return null==t||bt(n,t,Lu(t))},On.deburr=Tu,On.defaultTo=function(n,t){return null==n||n!==n?t:n},On.divide=rc,On.endsWith=function(n,t,r){n=zu(n),t=jr(t);var e=n.length,e=r=r===F?e:gt(Ou(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},On.eq=hu,On.escape=function(n){return(n=zu(n))&&Y.test(n)?n.replace(H,et):n},On.escapeRegExp=function(n){return(n=zu(n))&&fn.test(n)?n.replace(on,"\\$&"):n},On.every=function(n,t,r){var e=af(n)?o:wt;return r&&ze(n,t,r)&&(t=F),e(n,je(t,3));
+},On.find=Po,On.findIndex=Ze,On.findKey=function(n,t){return v(n,je(t,3),Et)},On.findLast=Zo,On.findLastIndex=qe,On.findLastKey=function(n,t){return v(n,je(t,3),Ot)},On.floor=ec,On.forEach=ru,On.forEachRight=eu,On.forIn=function(n,t){return null==n?n:co(n,je(t,3),Uu)},On.forInRight=function(n,t){return null==n?n:ao(n,je(t,3),Uu)},On.forOwn=function(n,t){return n&&Et(n,je(t,3))},On.forOwnRight=function(n,t){return n&&Ot(n,je(t,3))},On.get=Wu,On.gt=of,On.gte=ff,On.has=function(n,t){return null!=n&&ke(n,t,Bt);
+},On.hasIn=Bu,On.head=Ke,On.identity=Nu,On.includes=function(n,t,r,e){return n=pu(n)?n:Du(n),r=r&&!e?Ou(r):0,e=n.length,0>r&&(r=Di(e+r,0)),mu(n)?r<=e&&-1<n.indexOf(t,r):!!e&&-1<d(n,t,r)},On.indexOf=function(n,t,r){var e=null==n?0:n.length;return e?(r=null==r?0:Ou(r),0>r&&(r=Di(e+r,0)),d(n,t,r)):-1},On.inRange=function(n,t,r){return t=Eu(t),r===F?(r=t,t=0):r=Eu(r),n=Iu(n),n>=Mi(t,r)&&n<Di(t,r)},On.invoke=Sf,On.isArguments=cf,On.isArray=af,On.isArrayBuffer=lf,On.isArrayLike=pu,On.isArrayLikeObject=_u,
+On.isBoolean=function(n){return true===n||false===n||xu(n)&&"[object Boolean]"==zt(n)},On.isBuffer=sf,On.isDate=hf,On.isElement=function(n){return xu(n)&&1===n.nodeType&&!wu(n)},On.isEmpty=function(n){if(null==n)return true;if(pu(n)&&(af(n)||typeof n=="string"||typeof n.splice=="function"||sf(n)||gf(n)||cf(n)))return!n.length;var t=yo(n);if("[object Map]"==t||"[object Set]"==t)return!n.size;if(Le(n))return!Ht(n).length;for(var r in n)if(ci.call(n,r))return false;return true},On.isEqual=function(n,t){return Ft(n,t);
+},On.isEqualWith=function(n,t,r){var e=(r=typeof r=="function"?r:F)?r(n,t):F;return e===F?Ft(n,t,F,r):!!e},On.isError=vu,On.isFinite=function(n){return typeof n=="number"&&Li(n)},On.isFunction=gu,On.isInteger=du,On.isLength=yu,On.isMap=pf,On.isMatch=function(n,t){return n===t||Pt(n,t,me(t))},On.isMatchWith=function(n,t,r){return r=typeof r=="function"?r:F,Pt(n,t,me(t),r)},On.isNaN=function(n){return ju(n)&&n!=+n},On.isNative=function(n){if(bo(n))throw new Yu("Unsupported core-js use. Try https://npms.io/search?q=ponyfill.");
+return Zt(n)},On.isNil=function(n){return null==n},On.isNull=function(n){return null===n},On.isNumber=ju,On.isObject=bu,On.isObjectLike=xu,On.isPlainObject=wu,On.isRegExp=_f,On.isSafeInteger=function(n){return du(n)&&-9007199254740991<=n&&9007199254740991>=n},On.isSet=vf,On.isString=mu,On.isSymbol=Au,On.isTypedArray=gf,On.isUndefined=function(n){return n===F},On.isWeakMap=function(n){return xu(n)&&"[object WeakMap]"==yo(n)},On.isWeakSet=function(n){return xu(n)&&"[object WeakSet]"==zt(n)},On.join=function(n,t){
+return null==n?"":Ui.call(n,t)},On.kebabCase=Cf,On.last=Ge,On.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==F&&(u=Ou(r),u=0>u?Di(e+u,0):Mi(u,e-1)),t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=g(n,b,u,true);return n},On.lowerCase=Df,On.lowerFirst=Mf,On.lt=df,On.lte=yf,On.max=function(n){return n&&n.length?mt(n,Nu,Wt):F},On.maxBy=function(n,t){return n&&n.length?mt(n,je(t,2),Wt):F},On.mean=function(n){return x(n,Nu)},On.meanBy=function(n,t){return x(n,je(t,2))},On.min=function(n){
+return n&&n.length?mt(n,Nu,Jt):F},On.minBy=function(n,t){return n&&n.length?mt(n,je(t,2),Jt):F},On.stubArray=Ku,On.stubFalse=Gu,On.stubObject=function(){return{}},On.stubString=function(){return""},On.stubTrue=function(){return true},On.multiply=uc,On.nth=function(n,t){return n&&n.length?tr(n,Ou(t)):F},On.noConflict=function(){return Zn._===this&&(Zn._=pi),this},On.noop=qu,On.now=Jo,On.pad=function(n,t,r){n=zu(n);var e=(t=Ou(t))?T(n):0;return!t||e>=t?n:(t=(t-e)/2,ee(zi(t),r)+n+ee(Ri(t),r))},On.padEnd=function(n,t,r){
+n=zu(n);var e=(t=Ou(t))?T(n):0;return t&&e<t?n+ee(t-e,r):n},On.padStart=function(n,t,r){n=zu(n);var e=(t=Ou(t))?T(n):0;return t&&e<t?ee(t-e,r)+n:n},On.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),$i(zu(n).replace(an,""),t||0)},On.random=function(n,t,r){if(r&&typeof r!="boolean"&&ze(n,t,r)&&(t=r=F),r===F&&(typeof t=="boolean"?(r=t,t=F):typeof n=="boolean"&&(r=n,n=F)),n===F&&t===F?(n=0,t=1):(n=Eu(n),t===F?(t=n,n=0):t=Eu(t)),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Fi(),Mi(n+r*(t-n+$n("1e-"+((r+"").length-1))),t)):cr(n,t);
+},On.reduce=function(n,t,r){var e=af(n)?h:m,u=3>arguments.length;return e(n,je(t,4),r,u,oo)},On.reduceRight=function(n,t,r){var e=af(n)?p:m,u=3>arguments.length;return e(n,je(t,4),r,u,fo)},On.repeat=function(n,t,r){return t=(r?ze(n,t,r):t===F)?1:Ou(t),ar(zu(n),t)},On.replace=function(){var n=arguments,t=zu(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},On.result=function(n,t,r){t=Rr(t,n);var e=-1,u=t.length;for(u||(u=1,n=F);++e<u;){var i=null==n?F:n[$e(t[e])];i===F&&(e=u,i=r),n=gu(i)?i.call(n):i;
+}return n},On.round=ic,On.runInContext=w,On.sample=function(n){return(af(n)?tt:sr)(n)},On.size=function(n){if(null==n)return 0;if(pu(n))return mu(n)?T(n):n.length;var t=yo(n);return"[object Map]"==t||"[object Set]"==t?n.size:Ht(n).length},On.snakeCase=Tf,On.some=function(n,t,r){var e=af(n)?_:gr;return r&&ze(n,t,r)&&(t=F),e(n,je(t,3))},On.sortedIndex=function(n,t){return dr(n,t)},On.sortedIndexBy=function(n,t,r){return yr(n,t,je(r,2))},On.sortedIndexOf=function(n,t){var r=null==n?0:n.length;if(r){
+var e=dr(n,t);if(e<r&&hu(n[e],t))return e}return-1},On.sortedLastIndex=function(n,t){return dr(n,t,true)},On.sortedLastIndexBy=function(n,t,r){return yr(n,t,je(r,2),true)},On.sortedLastIndexOf=function(n,t){if(null==n?0:n.length){var r=dr(n,t,true)-1;if(hu(n[r],t))return r}return-1},On.startCase=$f,On.startsWith=function(n,t,r){return n=zu(n),r=null==r?0:gt(Ou(r),0,n.length),t=jr(t),n.slice(r,r+t.length)==t},On.subtract=oc,On.sum=function(n){return n&&n.length?k(n,Nu):0},On.sumBy=function(n,t){return n&&n.length?k(n,je(t,2)):0;
+},On.template=function(n,t,r){var e=On.templateSettings;r&&ze(n,t,r)&&(t=F),n=zu(n),t=jf({},t,e,se),r=jf({},t.imports,e.imports,se);var u,i,o=Lu(r),f=I(r,o),c=0;r=t.interpolate||An;var a="__p+='";r=ti((t.escape||An).source+"|"+r.source+"|"+(r===nn?gn:An).source+"|"+(t.evaluate||An).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(kn,B),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(q,""):a).replace(V,"$1").replace(K,"$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=Pf(function(){return Qu(o,l+"return "+a).apply(F,f)}),t.source=a,vu(t))throw t;return t},On.times=function(n,t){if(n=Ou(n),1>n||9007199254740991<n)return[];
+var r=4294967295,e=Mi(n,4294967295);for(t=je(t),n-=4294967295,e=E(e,t);++r<n;)t(r);return e},On.toFinite=Eu,On.toInteger=Ou,On.toLength=Su,On.toLower=function(n){return zu(n).toLowerCase()},On.toNumber=Iu,On.toSafeInteger=function(n){return n?gt(Ou(n),-9007199254740991,9007199254740991):0===n?n:0},On.toString=zu,On.toUpper=function(n){return zu(n).toUpperCase()},On.trim=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(cn,""):n&&(t=jr(t))?(n=$(n),r=$(t),t=z(n,r),r=W(n,r)+1,zr(n,t,r).join("")):n;
+},On.trimEnd=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(ln,""):n&&(t=jr(t))?(n=$(n),t=W(n,$(t))+1,zr(n,0,t).join("")):n},On.trimStart=function(n,t,r){return(n=zu(n))&&(r||t===F)?n.replace(an,""):n&&(t=jr(t))?(n=$(n),t=z(n,$(t)),zr(n,t).join("")):n},On.truncate=function(n,t){var r=30,e="...";if(bu(t))var u="separator"in t?t.separator:u,r="length"in t?Ou(t.length):r,e="omission"in t?jr(t.omission):e;n=zu(n);var i=n.length;if(Bn.test(n))var o=$(n),i=o.length;if(r>=i)return n;if(i=r-T(e),1>i)return e;
+if(r=o?zr(o,0,i).join(""):n.slice(0,i),u===F)return r+e;if(o&&(i+=r.length-i),_f(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=ti(u.source,zu(dn.exec(u))+"g")),u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===F?i:c)}}else n.indexOf(jr(u),i)!=i&&(u=r.lastIndexOf(u),-1<u&&(r=r.slice(0,u)));return r+e},On.unescape=function(n){return(n=zu(n))&&J.test(n)?n.replace(G,ut):n},On.uniqueId=function(n){var t=++ai;return zu(n)+t},On.upperCase=Ff,On.upperFirst=Nf,On.each=ru,On.eachRight=eu,On.first=Ke,
+Zu(On,function(){var n={};return Et(On,function(t,r){ci.call(On.prototype,r)||(n[r]=t)}),n}(),{chain:false}),On.VERSION="4.17.4",u("bind bindKey curry curryRight partial partialRight".split(" "),function(n){On[n].placeholder=On}),u(["drop","take"],function(n,t){Mn.prototype[n]=function(r){r=r===F?1:Di(Ou(r),0);var e=this.__filtered__&&!t?new Mn(this):this.clone();return e.__filtered__?e.__takeCount__=Mi(r,e.__takeCount__):e.__views__.push({size:Mi(r,4294967295),type:n+(0>e.__dir__?"Right":"")}),e},Mn.prototype[n+"Right"]=function(t){
+return this.reverse()[n](t).reverse()}}),u(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Mn.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:je(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),u(["head","last"],function(n,t){var r="take"+(t?"Right":"");Mn.prototype[n]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Mn.prototype[n]=function(){return this.__filtered__?new Mn(this):this[r](1);
+}}),Mn.prototype.compact=function(){return this.filter(Nu)},Mn.prototype.find=function(n){return this.filter(n).head()},Mn.prototype.findLast=function(n){return this.reverse().find(n)},Mn.prototype.invokeMap=lr(function(n,t){return typeof n=="function"?new Mn(this):this.map(function(r){return Dt(r,n,t)})}),Mn.prototype.reject=function(n){return this.filter(su(je(n)))},Mn.prototype.slice=function(n,t){n=Ou(n);var r=this;return r.__filtered__&&(0<n||0>t)?new Mn(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),
+t!==F&&(t=Ou(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Mn.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Mn.prototype.toArray=function(){return this.take(4294967295)},Et(Mn.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=On[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(On.prototype[t]=function(){function t(n){return n=u.apply(On,s([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Mn,a=f[0],l=c||af(o);
+l&&r&&typeof a=="function"&&1!=a.length&&(c=l=false);var h=this.__chain__,p=!!this.__actions__.length,a=i&&!h,c=c&&!p;return!i&&l?(o=c?o:new Mn(this),o=n.apply(o,f),o.__actions__.push({func:nu,args:[t],thisArg:F}),new zn(o,h)):a&&c?n.apply(this,f):(o=this.thru(t),a?e?o.value()[0]:o.value():o)})}),u("pop push shift sort splice unshift".split(" "),function(n){var t=ui[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);On.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){
+var u=this.value();return t.apply(af(u)?u:[],n)}return this[r](function(r){return t.apply(af(r)?r:[],n)})}}),Et(Mn.prototype,function(n,t){var r=On[t];if(r){var e=r.name+"";(Ji[e]||(Ji[e]=[])).push({name:t,func:r})}}),Ji[Xr(F,2).name]=[{name:"wrapper",func:F}],Mn.prototype.clone=function(){var n=new Mn(this.__wrapped__);return n.__actions__=Mr(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Mr(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Mr(this.__views__),
+n},Mn.prototype.reverse=function(){if(this.__filtered__){var n=new Mn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Mn.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=af(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=Mi(n,f+s);break;case"takeRight":f=Di(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=Mi(n,this.__takeCount__),!e||!u&&i==n&&l==n)return kr(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},On.prototype.at=Fo,On.prototype.chain=function(){return Xe(this)},On.prototype.commit=function(){return new zn(this.value(),this.__chain__)},On.prototype.next=function(){this.__values__===F&&(this.__values__=ku(this.value()));
+var n=this.__index__>=this.__values__.length;return{done:n,value:n?F:this.__values__[this.__index__++]}},On.prototype.plant=function(n){for(var t,r=this;r instanceof Sn;){var e=Pe(r);e.__index__=0,e.__values__=F,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},On.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Mn?(this.__actions__.length&&(n=new Mn(this)),n=n.reverse(),n.__actions__.push({func:nu,args:[Je],thisArg:F}),new zn(n,this.__chain__)):this.thru(Je);
+},On.prototype.toJSON=On.prototype.valueOf=On.prototype.value=function(){return kr(this.__wrapped__,this.__actions__)},On.prototype.first=On.prototype.head,Ai&&(On.prototype[Ai]=tu),On}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Zn._=it, define(function(){return it})):Vn?((Vn.exports=it)._=it,qn._=it):Zn._=it}).call(this); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js b/vid-app-common/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js
new file mode 100644
index 000000000..b9be2c7e4
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/external/multiselect/angular-bootstrap-multiselect.min.js
@@ -0,0 +1 @@
+!function(){"use strict";var a=angular.module("btorfs.multiselect",["btorfs.multiselect.templates"]);a.getRecursiveProperty=function(a,b){return b.split(".").reduce(function(a,b){return a?a[b]:null},a)},a.directive("multiselect",["$filter","$document","$log",function(b,c,d){return{restrict:"AE",scope:{options:"=",displayProp:"@",idProp:"@",searchLimit:"=?",selectionLimit:"=?",showSelectAll:"=?",showUnselectAll:"=?",showSearch:"=?",searchFilter:"=?",disabled:"=?ngDisabled",labels:"=?",showTooltip:"=?",placeholder:"@?"},require:"ngModel",templateUrl:"multiselect.html",link:function(b,e,f,g){b.selectionLimit=b.selectionLimit||0,b.searchLimit=b.searchLimit||25,b.searchFilter="",b.resolvedOptions=[],"function"!=typeof b.options&&(b.resolvedOptions=b.options),"undefined"!=typeof f.disabled&&(b.disabled=!0);var h=function(a){e[0].contains(a.target)||b.$apply(function(){b.open=!1})};c.on("click",h);var i=function(){g.$viewValue?(b.selectedOptions=b.resolvedOptions.filter(function(a){for(var c=b.getId(a),d=0;d<g.$viewValue.length;d++){var e=b.getId(g.$viewValue[d]);if(c===e)return!0}return!1}),b.unselectedOptions=b.resolvedOptions.filter(function(a){return b.selectedOptions.indexOf(a)<0})):(b.selectedOptions&&(b.selectedOptions=[]),b.unselectedOptions=b.resolvedOptions.slice())};b.toggleDropdown=function(){b.open=!b.open,b.resolvedOptions=b.options,i()},g.$render=function(){i()},g.$viewChangeListeners.push(function(){i()}),g.$isEmpty=function(a){return!a||0===a.length};var j=b.$watch("selectedOptions",function(){g.$setViewValue(angular.copy(b.selectedOptions))},!0);b.$on("$destroy",function(){c.off("click",h),j&&j()}),b.getButtonText=function(){if(b.selectedOptions&&1===b.selectedOptions.length)return b.getDisplay(b.selectedOptions[0]);if(b.selectedOptions&&b.selectedOptions.length>1){var a=angular.isDefined(b.selectedOptions)?b.selectedOptions.length:0;return 0===a?b.labels&&b.labels.select?b.labels.select:b.placeholder||"Select":a+" "+(b.labels&&b.labels.itemsSelected?b.labels.itemsSelected:"selected")}return b.labels&&b.labels.select?b.labels.select:b.placeholder||"Select"},b.selectAll=function(){b.selectedOptions=b.resolvedOptions.slice(),b.unselectedOptions=[]},b.unselectAll=function(){b.selectedOptions=[],b.unselectedOptions=b.resolvedOptions.slice()},b.toggleItem=function(a){"undefined"==typeof b.selectedOptions&&(b.selectedOptions=[]);var c=b.selectedOptions.indexOf(a),d=c!==-1;if(d)b.unselectedOptions.push(b.selectedOptions[c]),b.selectedOptions.splice(c,1);else if(!d&&(0===b.selectionLimit||b.selectedOptions.length<b.selectionLimit)){var e=b.unselectedOptions.indexOf(a);b.unselectedOptions.splice(e,1),b.selectedOptions.push(a)}},b.getId=function(c){return angular.isString(c)?c:angular.isObject(c)?b.idProp?a.getRecursiveProperty(c,b.idProp):(d.error("Multiselect: when using objects as model, a idProp value is mandatory."),""):c},b.getDisplay=function(c){return angular.isString(c)?c:angular.isObject(c)?b.displayProp?a.getRecursiveProperty(c,b.displayProp):(d.error("Multiselect: when using objects as model, a displayProp value is mandatory."),""):c},b.isSelected=function(a){if(!b.selectedOptions)return!1;for(var c=b.getId(a),d=0;d<b.selectedOptions.length;d++){var e=b.selectedOptions[d];if(b.getId(e)===c)return!0}return!1},b.updateOptions=function(){"function"==typeof b.options&&b.options().then(function(a){b.resolvedOptions=a,i()})},b.search=function(){var a=0;return function(c){if(a>b.searchLimit)return!1;var d=b.getDisplay(c);if(d){var e=d.toLowerCase().indexOf(b.searchFilter.toLowerCase())>-1;return e&&a++,e}}}}}}])}(),angular.module("btorfs.multiselect.templates",["multiselect.html"]),angular.module("multiselect.html",[]).run(["$templateCache",function(a){a.put("multiselect.html",'<div class="btn-group" style="width: 100%">\n <button type="button" class="btn btn-default btn-block dropdown-toggle" ng-click="toggleDropdown()" ng-disabled="disabled" style="white-space: nowrap; overflow-x: hidden; text-overflow: ellipsis;">\n {{getButtonText()}}&nbsp;<span class="caret"></span>\n </button>\n <ul class="dropdown-menu dropdown-menu-form"\n ng-style="{display: open ? \'block\' : \'none\'}" style="width: 100%; overflow-x: auto">\n\n <li ng-show="showSelectAll">\n <a ng-click="selectAll()" href="">\n <span class="glyphicon glyphicon-ok"></span> {{labels.selectAll || \'Select All\'}}\n </a>\n </li>\n <li ng-show="showUnselectAll">\n <a ng-click="unselectAll()" href="">\n <span class="glyphicon glyphicon-remove"></span> {{labels.unselectAll || \'Unselect All\'}}\n </a>\n </li>\n <li ng-show="(showSelectAll || showUnselectAll)"\n class="divider">\n </li>\n\n <li role="presentation" ng-repeat="option in selectedOptions" class="active">\n <a class="item-selected" href="" title="{{showTooltip ? getDisplay(option) : \'\'}}" ng-click="toggleItem(option); $event.stopPropagation()" style="overflow-x: auto">\n <span class="glyphicon glyphicon-remove"></span>\n {{getDisplay(option)}}\n </a>\n </li>\n <li ng-show="selectedOptions.length > 0" class="divider"></li>\n\n <li ng-show="showSearch">\n <div class="dropdown-header">\n <input type="text" class="form-control input-sm" style="width: 100%;"\n ng-model="searchFilter" placeholder="{{labels.search || \'Search...\'}}" ng-change="updateOptions()"/>\n </div>\n </li>\n\n <li ng-show="showSearch" class="divider"></li>\n <li role="presentation" ng-repeat="option in unselectedOptions | filter:search() | limitTo: searchLimit"\n ng-if="!isSelected(option)"\n ng-class="{disabled : selectionLimit && selectedOptions.length >= selectionLimit}">\n <a class="item-unselected" href="" title="{{showTooltip ? getDisplay(option) : \'\'}}" ng-click="toggleItem(option); $event.stopPropagation()" style="overflow-x: auto">\n {{getDisplay(option)}}\n </a>\n </li>\n\n <li class="divider" ng-show="selectionLimit > 1"></li>\n <li role="presentation" ng-show="selectionLimit > 1">\n <a>{{selectedOptions.length || 0}} / {{selectionLimit}} {{labels.itemsSelected || \'selected\'}}</a>\n </li>\n\n </ul>\n</div>\n')}]); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/images/Calendar.svg b/vid-app-common/src/main/webapp/app/vid/images/Calendar.svg
new file mode 100644
index 000000000..23090539e
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/images/Calendar.svg
@@ -0,0 +1,39 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="18" height="19" viewBox="0 0 18 19">
+ <metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""/>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?></metadata>
+<defs>
+ <style>
+ .cls-1 {
+ fill: #646464;
+ fill-rule: evenodd;
+ }
+ </style>
+ </defs>
+ <path id="Calendar" class="cls-1" d="M1332.5,326a0.5,0.5,0,0,1,.5.5v4a0.5,0.5,0,0,1-1,0v-4A0.5,0.5,0,0,1,1332.5,326Zm-7,0a0.5,0.5,0,0,1,.5.5v4a0.5,0.5,0,0,1-1,0v-4A0.5,0.5,0,0,1,1325.5,326Zm12.5,5.968c0-3.02-.93-3.968-4-3.968h-10c-3.07,0-4,.948-4,3.968V340c0,3.019.93,5,4,5h10c3.07,0,4-1.981,4-5v-8.032Zm-17.15,0c0-2.558.55-2.968,3.15-2.968h10c2.6,0,3.15.41,3.15,2.968L1337,333h-16ZM1337,340c0,2.558-.4,4-3,4h-10c-2.6,0-3-1.442-3-4v-6h16v6Zm-11.5-3h7a0.5,0.5,0,0,1,0,1h-7A0.5,0.5,0,0,1,1325.5,337Zm0,3h7a0.5,0.5,0,0,1,0,1h-7A0.5,0.5,0,0,1,1325.5,340Z" transform="translate(-1320 -326)"/>
+</svg>
diff --git a/vid-app-common/src/main/webapp/app/vid/images/Calendar_blue.svg b/vid-app-common/src/main/webapp/app/vid/images/Calendar_blue.svg
new file mode 100644
index 000000000..f5ac20b2b
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/images/Calendar_blue.svg
@@ -0,0 +1,45 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="19" viewBox="0 0 18 19">
+ <metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
+<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
+ <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
+ <rdf:Description rdf:about=""/>
+ </rdf:RDF>
+</x:xmpmeta>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<?xpacket end="w"?></metadata>
+<defs>
+ <style>
+ .cls-1 {
+ fill: #646464;
+ fill-rule: evenodd;
+ filter: url(#filter);
+ }
+ </style>
+ <filter id="filter" x="1320" y="326" width="18" height="19" filterUnits="userSpaceOnUse">
+ <feFlood result="flood" flood-color="#009fdb"/>
+ <feComposite result="composite" operator="in" in2="SourceGraphic"/>
+ <feBlend result="blend" in2="SourceGraphic"/>
+ </filter>
+ </defs>
+ <path id="Calendar" class="cls-1" d="M1332.5,326a0.5,0.5,0,0,1,.5.5v4a0.5,0.5,0,0,1-1,0v-4A0.5,0.5,0,0,1,1332.5,326Zm-7,0a0.5,0.5,0,0,1,.5.5v4a0.5,0.5,0,0,1-1,0v-4A0.5,0.5,0,0,1,1325.5,326Zm12.5,5.968c0-3.02-.93-3.968-4-3.968h-10c-3.07,0-4,.948-4,3.968V340c0,3.019.93,5,4,5h10c3.07,0,4-1.981,4-5v-8.032Zm-17.15,0c0-2.558.55-2.968,3.15-2.968h10c2.6,0,3.15.41,3.15,2.968L1337,333h-16ZM1337,340c0,2.558-.4,4-3,4h-10c-2.6,0-3-1.442-3-4v-6h16v6Zm-11.5-3h7a0.5,0.5,0,0,1,0,1h-7A0.5,0.5,0,0,1,1325.5,337Zm0,3h7a0.5,0.5,0,0,1,0,1h-7A0.5,0.5,0,0,1,1325.5,340Z" transform="translate(-1320 -326)"/>
+</svg>
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 f88ee9c35..534cee505 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
@@ -20,7 +20,9 @@
"use strict";
-appDS2.constant("COMPONENT", (function() {
+appDS2
+ .constant("_", window._)
+ .constant("COMPONENT", (function() {
return {
A_LA_CARTE : "a la carte",
CLOUD_REGION_ID : "cloudRegionID",
@@ -95,16 +97,30 @@ appDS2.constant("COMPONENT", (function() {
VPN_ID_1 : "1a2b3c4d5e6f",
// PATHS
+ GET_WORKFLOW: "change-management/workflow?vnfs=@vnfs",
+ GET_MSO_WORKFLOWS: "change-management/mso",
+ GET_SCHEDULER_CHANGE_MANAGEMENTS: "change-management/scheduler",
ASSIGN : "?r=",
AAI_GET_SERVICE_INSTANCE_PATH : "aai_get_service_instance/",
AAI_GET_SERVICES : "aai_get_services",
AAI_GET_AIC_ZONES :"aai_get_aic_zones",
+ AAI_GET_AIC_ZONE_FOR_PNF :"aai_get_aic_zone_for_pnf/@globalCustomerId/@serviceType/@serviceInstanceId",
AAI_GET_SERVICES_BY_TYPE : "aai_get_models_by_service_type",
AAI_GET_TENANTS : "aai_get_tenants/",
AAI_SUB_DETAILS_PATH : "aai_sub_details/",
+ AAI_GET_VERSION_BY_INVARIANT_ID:"aai_get_version_by_invariant_id/",
+ AAI_GET_VNF_DATA_PATH: "aai_get_vnf_data/",
+ AAI_GET_VNF_BY_CUSTOMERID_AND_SERVICETYPE: "get_vnf_data_by_globalid_and_service_type/",
AAI_SUB_VIEWEDIT_PATH : "aai_sub_viewedit",
+ AAI_GET_VNF_INFO : "aai_get_vnf_information",
ASDC_GETMODEL_PATH : "asdc/getModel/",
CREATE_INSTANCE_PATH : "/models/services/createInstance",
+ //1710 scheduler contants
+ POST_CREATE_NEW_VNF_CHANGE:"post_create_new_vnf_change",
+ GET_POLICY:"get_policy",
+ GET_TIME_SLOTS:"get_time_slots",
+ SUBMIT_VNF_CHANGE_TIMESLOTS:"submit_vnf_change_timeslots",
+
FORWARD_SLASH : "/",
GET_SYSTEM_PROP_VNF_PROV_STATUS_PATH : "get_system_prop_vnf_prov_status",
GET_USER_ID : "getuserID",
@@ -116,6 +132,7 @@ appDS2.constant("COMPONENT", (function() {
MSO_CREATE_NW_INSTANCE_PATH : "mso_create_nw_instance/",
MSO_CREATE_SVC_INSTANCE : "mso_create_svc_instance",
MSO_DELETE_SVC_INSTANCE_PATH : "mso_delete_svc_instance/",
+ MSO_ACTIVATE_INSTANCE: "mso/mso_activate_service_instance/@serviceInstanceId",
SELECTED_SERVICE_SUB_PATH : "#/instances/subdetails?selectedServiceSubscription=",
SELECTED_SUB_PATH : "#/instances/subdetails?selectedSubscriber=",
SELECTEDSERVICEINSTANCE_SUB_PATH : "&selectedServiceInstance=",
@@ -154,6 +171,13 @@ appDS2.constant("COMPONENT", (function() {
"vfmodule" : "VF Module",
"vnf" : "VNF",
"volumegroup" : "Volume Group"
+ },
+
+ MANUAL_TASKS: {
+ "retry": "retry",
+ "rollback": "rollback",
+ "abort": "abort",
+ "skip": "skip"
}
};
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/constants/fieldConstants.js b/vid-app-common/src/main/webapp/app/vid/scripts/constants/fieldConstants.js
index 9d337fa11..9e3f44cc2 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/constants/fieldConstants.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/constants/fieldConstants.js
@@ -31,7 +31,7 @@ appDS2.factory("FIELD", ["PARAMETER", function (PARAMETER) {
LCP_REGION: "lcpRegion",
LCP_REGION_TEXT: "lcpRegionText",
PRODUCT_FAMILY: "productFamily",
- AIC_ZONES : "aic_zone",
+ AIC_ZONES: "aic_zone",
SERVICE_TYPE: "serviceType",
SERVICE_ROLE: "serviceRole",
SUBSCRIBER_NAME: "subscriberName",
@@ -127,8 +127,8 @@ appDS2.factory("FIELD", ["PARAMETER", function (PARAMETER) {
SDN_C_PRELOAD: "sdncPreload",
UPLOAD_SUPPLEMENTORY_DATA_FILE: "uploadSupplementoryDataFile",
SUPPLEMENTORY_DATA_FILE: "supplementoryDataFile",
- ZONE_ID:"zone-id",
- ZONE_NAME:"zone-name",
+ ZONE_ID: "zone-id",
+ ZONE_NAME: "zone-name",
};
@@ -140,57 +140,58 @@ appDS2.factory("FIELD", ["PARAMETER", function (PARAMETER) {
* NAME values are displayed on GUI pages.
*/
var NAME = {
- AVAILABLE_VOLUME_GROUP : "Available Volume Group",
- INSTANCE_NAME : "Instance Name",
- CUSTOMER_ID : "Customer ID",
- LCP_REGION : "LCP Region",
- LCP_REGION_TEXT : "Legacy Region",
- MODEL_INVARIANT_UUID: "Model Invariant UUID",
- MODEL_NAME: "Model Name",
- MODEL_VERSION: "Model Version",
- MODEL_UUID: "Model UUID",
- MODEL_CUSTOMIZATION_UUID: "Model Customization UUID",
- MODEL_VNF_TYPE: "NF Type",
- MODEL_VNF_ROLE: "NF Role",
- MODEL_VNF_FUNCTION: "NF Function",
- MODEL_VNF_CODE: "NF Naming Code",
- MODEL_CUSTOMIZATION_NAME: "Resource Name",
- PRODUCT_FAMILY : "Product Family",
+ AVAILABLE_VOLUME_GROUP: "Available Volume Group",
+ INSTANCE_NAME: "Instance Name",
+ CUSTOMER_ID: "Customer ID",
+ LCP_REGION: "LCP Region",
+ LCP_REGION_TEXT: "Legacy Region",
+ MODEL_INVARIANT_UUID: "Model Invariant UUID",
+ MODEL_NAME: "Model Name",
+ MODEL_VERSION: "Model Version",
+ MODEL_UUID: "Model UUID",
+ MODEL_CUSTOMIZATION_UUID: "Model Customization UUID",
+ MODEL_VNF_TYPE: "NF Type",
+ MODEL_VNF_ROLE: "NF Role",
+ MODEL_VNF_FUNCTION: "NF Function",
+ MODEL_VNF_CODE: "NF Naming Code",
+ MODEL_CUSTOMIZATION_NAME: "Resource Name",
+ PRODUCT_FAMILY: "Product Family",
AIC_ZONES: "AIC Zone",
- RESOURCE_DESCRIPTION : "Resource Description",
- RESOURCE_NAME : "Resource Name",
- SERVICE_CATEGORY : "Service Category",
- SERVICE_DESCRIPTION : "Service Description",
- SERVICE_INSTANCE_ID : "Service Instance ID",
- SERVICE_INSTANCE_Id : "Service Instance Id",
- SERVICE_INSTANCE_NAME : "Service Instance Name",
- SERVICE_INVARIANT_UUID : "Service Invariant UUID",
- SERVICE_NAME : "Service Name",
- SERVICE_TYPE : "Service Type",
- SERVICE_UUID : "Service UUID",
- SERVICE_VERSION : "Service Version",
- SUBSCRIBER_NAME : "Subscriber Name",
- MOBILITY : "Mobility",
- SUPPRESS_ROLLBACK : "Suppress Rollback on Failure",
- SDN_C_PRELOAD : "SDN-C Pre-Load",
- UPLOAD_SUPPLEMENTORY_DATA_FILE : "Upload Supplementary Data file",
- SUPPLEMENTORY_DATA_FILE : "Supplementory Data file (JSON format)",
- TENANT : "Tenant",
- USER_SERVICE_INSTANCE_NAME : "User Service Instance Name",
- VF_MODULE_DESCRIPTION : "VF Module Description",
- VF_MODULE_LABEL : "VF Module Label",
- VF_MODULE_TYPE : "VF Module Type",
- VNF_ORCHESTRATION_STATUS : "Orchestration Status",
- VNF_Operational_Status: "Operational Status",
- VNF_Current_Prov_Status: "Current Prov_Status",
- VNF_Target_Prov_Status: "Target Prov Status",
- VNF_VNF_ID : "VNF ID",
- VNF_VNF_Name: "VNF Name",
- VNF_VNF_Type: "VNF Type",
- VNF_Service_ID: "Service ID",
- VNF_In_Maint: "In Maint",
- VFMDULE_CUSTOMIZATIONUUID: "VF Module Model Customization UUID",
- RESOURCE_CUSTOMIZATION_UUID: "Resource Model Customization UUID"
+ RESOURCE_DESCRIPTION: "Resource Description",
+ RESOURCE_NAME: "Resource Name",
+ SERVICE_CATEGORY: "Service Category",
+ SERVICE_DESCRIPTION: "Service Description",
+ SERVICE_INSTANCE_ID: "Service Instance ID",
+ SERVICE_INSTANCE_Id: "Service Instance Id",
+ SERVICE_INSTANCE_NAME: "Service Instance Name",
+ SERVICE_INVARIANT_UUID: "Service Invariant UUID",
+ SERVICE_NAME: "Service Name",
+ SERVICE_TYPE: "Service Type",
+ SERVICE_ROLE: "Service Role",
+ SERVICE_UUID: "Service UUID",
+ SERVICE_VERSION: "Service Version",
+ SUBSCRIBER_NAME: "Subscriber Name",
+ MOBILITY: "Mobility",
+ SUPPRESS_ROLLBACK: "Suppress Rollback on Failure",
+ SDN_C_PRELOAD: "SDN-C Pre-Load",
+ UPLOAD_SUPPLEMENTORY_DATA_FILE: "Upload Supplementary Data file",
+ SUPPLEMENTORY_DATA_FILE: "Supplementory Data file (JSON format)",
+ TENANT: "Tenant",
+ USER_SERVICE_INSTANCE_NAME: "User Service Instance Name",
+ VF_MODULE_DESCRIPTION: "VF Module Description",
+ VF_MODULE_LABEL: "VF Module Label",
+ VF_MODULE_TYPE: "VF Module Type",
+ VNF_ORCHESTRATION_STATUS: "Orchestration Status",
+ VNF_Operational_Status: "Operational Status",
+ VNF_Current_Prov_Status: "Current Prov_Status",
+ VNF_Target_Prov_Status: "Target Prov Status",
+ VNF_VNF_ID: "VNF ID",
+ VNF_VNF_Name: "VNF Name",
+ VNF_VNF_Type: "VNF Type",
+ VNF_Service_ID: "Service ID",
+ VNF_In_Maint: "In Maint",
+ VFMDULE_CUSTOMIZATIONUUID: "VF Module Model Customization UUID",
+ RESOURCE_CUSTOMIZATION_UUID: "Resource Model Customization UUID"
};
/*
@@ -267,29 +268,29 @@ appDS2.factory("FIELD", ["PARAMETER", function (PARAMETER) {
}
var ERROR = {
- AAI : "A&AI failure - see log below for details",
- AAI_ERROR : "A&AI Error",
- AAI_FETCHING_CUST_DATA : "Failed to fetch customer data from A&AI: Response Code: ",
- FETCHING_SERVICE_TYPES : "Failed to fetch service types from A&AI: Response Code: ",
- FETCHING_SERVICES : "Failed to fetch services from A&AI: Response Code: ",
- FETCHING_SERVICE_INSTANCE_DATA : "Failed to fetch service instance data from A&AI: Response Code: ",
- INVALID_INSTANCE_NAME : "Invalid instance name: ",
- INSTANCE_NAME_VALIDATE : "The instance name must contain only alphanumeric or \"_-.\" characters, and must start with an alphabetic character",
- INVALID_LIST : "Invalid list parameter: ",
- INVALID_MAP : "Invalid map parameter: ",
- LIST_VALIDATE : "A list parameter value must have the following syntax: '[<value1>,\.\.\.,<valueN>]'",
- MAP_VALIDATE : "A map parameter value must have the following syntax: '{ <entry_key_1>: <entry_value_1>, \.\.\., <entry_key_n>: <entry_value_n> }'",
- MAX_POLLS_EXCEEDED : "Maximum number of poll attempts exceeded",
- MISSING_DATA : "Missing data",
- MODEL_VERSION_ID_MISSING : "Error: model-version-id is not populated in A&AI",
- MSO : "MSO failure - see log below for details",
- NO_MATCHING_MODEL : "No matching model found matching the persona Model Id = ",
- NO_MATCHING_MODEL_AAI : "No matching model found matching the A&AI model version ID = ",
- SELECT : "Please select a subscriber or enter a service instance",
- SERVICE_INST_DNE : "That service instance does not exist. Please try again.",
- SYSTEM_FAILURE : "System failure",
- INVALID_DATA_FORMAT : 'Invalid data format.Please check your file content whether it is not in json or not.',
- MISSING_FILE : 'Please Select JSON File.',
+ AAI: "A&AI failure - see log below for details",
+ AAI_ERROR: "A&AI Error",
+ AAI_FETCHING_CUST_DATA: "Failed to fetch customer data from A&AI: Response Code: ",
+ FETCHING_SERVICE_TYPES: "Failed to fetch service types from A&AI: Response Code: ",
+ FETCHING_SERVICES: "Failed to fetch services from A&AI: Response Code: ",
+ FETCHING_SERVICE_INSTANCE_DATA: "Failed to fetch service instance data from A&AI: Response Code: ",
+ INVALID_INSTANCE_NAME: "Invalid instance name: ",
+ INSTANCE_NAME_VALIDATE: "The instance name must contain only alphanumeric or \"_-.\" characters, and must start with an alphabetic character",
+ INVALID_LIST: "Invalid list parameter: ",
+ INVALID_MAP: "Invalid map parameter: ",
+ LIST_VALIDATE: "A list parameter value must have the following syntax: '[<value1>,\.\.\.,<valueN>]'",
+ MAP_VALIDATE: "A map parameter value must have the following syntax: '{ <entry_key_1>: <entry_value_1>, \.\.\., <entry_key_n>: <entry_value_n> }'",
+ MAX_POLLS_EXCEEDED: "Maximum number of poll attempts exceeded",
+ MISSING_DATA: "Missing data",
+ MODEL_VERSION_ID_MISSING: "Error: model-version-id is not populated in A&AI",
+ MSO: "MSO failure - see log below for details",
+ NO_MATCHING_MODEL: "No matching model found matching the persona Model Id = ",
+ NO_MATCHING_MODEL_AAI: "No matching model found matching the A&AI model version ID = ",
+ SELECT: "Please select a subscriber or enter a service instance",
+ SERVICE_INST_DNE: "That service instance does not exist. Please try again.",
+ SYSTEM_FAILURE: "System failure",
+ INVALID_DATA_FORMAT: 'Invalid data format.Please check your file content whether it is not in json or not.',
+ MISSING_FILE: 'Please Select JSON File.',
}
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/constants/vidConfiguration.js b/vid-app-common/src/main/webapp/app/vid/scripts/constants/vidConfiguration.js
index 4341a4cac..ee33875b9 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/constants/vidConfiguration.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/constants/vidConfiguration.js
@@ -84,6 +84,10 @@ appDS2.constant("VIDCONFIGURATION", (function() {
* Number of msecs that VID will wait between MSO polls.
*/
var MSO_POLLING_INTERVAL_MSECS = 10000;
+
+ var SCHEDULER_POLLING_INTERVAL_MSECS = 10000;
+
+ var SCHEDULER_MAX_POLLS = 10;
/*
* List of all service model invariant UUIDs that need macro instantiation.
* Example:
@@ -91,14 +95,16 @@ appDS2.constant("VIDCONFIGURATION", (function() {
*
*/
var COMPONENT_LIST_NAMED_QUERY_ID = "0367193e-c785-4d5f-9cb8-7bc89dc9ddb7";
- var MACRO_SERVICES = ["93150ffa-00c6-4ea0-85f2-3536ca46ebd2",
+ var MACRO_SERVICES = ["c9514b73-3dfe-4d7e-9146-b318d48655d9", "93150ffa-00c6-4ea0-85f2-3536ca46ebd2",
"2b54297f-72e7-4a94-b451-72df88d0be0b",
"d27e42cf-087e-4d31-88ac-6c4b7585f800",
- "ec0c4bab-c272-4dab-b087-875031bb0c9f","0311f998-9268-4fd6-bbba-afff15087b72"];
+ "ec0c4bab-c272-4dab-b087-875031bb0c9f","0311f998-9268-4fd6-bbba-afff15087b72","43596836-ae36-4608-a987-6608ede10dac","306caa85-74c7-48a9-aa22-7e3a564b957a"];
return {
ASDC_MODEL_STATUS : ASDC_MODEL_STATUS,
MSO_MAX_POLLS : MSO_MAX_POLLS,
MSO_POLLING_INTERVAL_MSECS : MSO_POLLING_INTERVAL_MSECS,
+ SCHEDULER_MAX_POLLS : SCHEDULER_MAX_POLLS,
+ SCHEDULER_POLLING_INTERVAL_MSECS : SCHEDULER_POLLING_INTERVAL_MSECS,
VNF_STATUS_CHECK_ENABLED : VNF_STATUS_CHECK_ENABLED,
VNF_VALID_STATUS_LIST : vnfValidStatusList,
UPLOAD_SUPPLEMENTARY_STATUS_CHECK_ENABLED : UPLOAD_SUPPLEMENTARY_STATUS_CHECK_ENABLED,
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 b0fcb11e2..f0653f680 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
@@ -352,9 +352,6 @@
$scope.deleteVnf = function(serviceObject, vnf) {
-
- debugger;
-
console.log("Removing VNF " + vnf.name);
var serviceInstance = serviceObject.object;
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 731c2f2e8..a0030889a 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
@@ -39,8 +39,8 @@
$http.get(pathQuery)
.then(function successCallback(response) {
$scope.services = [];
- if (angular.isArray(response.data.services)) {
- wholeData = response.data.services;
+ if (angular.isArray(response.data)) {
+ wholeData = response.data;
$scope.services = $scope.filterDataWithHigerVersion(wholeData);
$scope.viewPerPage=10;
$scope.totalPage=$scope.services.length/$scope.viewPerPage;
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/VidApp.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/VidApp.js
index dcde2ecc6..b611def42 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/VidApp.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/VidApp.js
@@ -47,6 +47,11 @@
templateUrl : "app/vid/scripts/view-models/aaiSubDetails.htm",
controller : "aaiSubscriberController"
})
+ .when('/change-management', {
+ templateUrl : "app/vid/scripts/view-models/change-management.html",
+ controller : "changeManagementController",
+ controllerAs: 'vm'
+ })
.when('/instantiate', {
controller: 'InstantiationController',
templateUrl: 'app/vid/scripts/view-models/instantiate.htm'
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js
index 84d27a230..6bf16c349 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/aaiSubscriberController.js
@@ -20,8 +20,8 @@
"use strict";
-appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", "DataService", "PropertyService", "$scope", "$http", "$timeout", "$location", "$log", "$route", "VIDCONFIGURATION", "UtilityService", "vidService", "AaiService",
- function (COMPONENT, FIELD, PARAMETER, DataService, PropertyService, $scope, $http, $timeout, $location, $log, $route, VIDCONFIGURATION, UtilityService, vidService, AaiService) {
+appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER", "DataService", "PropertyService", "$scope", "$http", "$timeout", "$location", "$log", "$route", "VIDCONFIGURATION", "UtilityService", "vidService", "AaiService", "MsoService",
+ function (COMPONENT, FIELD, PARAMETER, DataService, PropertyService, $scope, $http, $timeout, $location, $log, $route, VIDCONFIGURATION, UtilityService, vidService, AaiService, MsoService) {
$scope.showVnfDetails = function (vnf) {
console.log("showVnfDetails");
@@ -901,6 +901,17 @@ appDS2.controller("aaiSubscriberController", ["COMPONENT", "FIELD", "PARAMETER",
$scope.currentPage--;
}
+ $scope.activateMSOInstance = function() {
+ MsoService.activateInstance($scope.service.instance, $scope.service.model)
+ .then(function(response) {
+ alert("Activation succeeded");
+ })
+ .catch(function (error) {
+ $log.error(error);
+ });
+ ;
+ };
+
$scope.nextPage = function () {
$scope.currentPage++;
}
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/controller/change-management.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/controller/change-management.controller.js
new file mode 100644
index 000000000..662b10ecd
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/controller/change-management.controller.js
@@ -0,0 +1,138 @@
+(function () {
+ 'use strict';
+
+ appDS2.controller("changeManagementController", ["$uibModal", "changeManagementService", "_", "$log", changeManagementController]);
+
+ function changeManagementController($uibModal, changeManagementService, _, $log) {
+ var vm = this;
+
+ var init = function() {
+ loadMSOChangeManagements();
+ loadSchedulerChangeManagements();
+ };
+
+ var loadMSOChangeManagements = function() {
+ changeManagementService.getMSOChangeManagements()
+ .then(function(response) {
+ vm.changeManagements = response.data;
+ })
+ .catch(function (error) {
+ $log.error(error);
+ });
+ };
+
+ var loadSchedulerChangeManagements = function() {
+ changeManagementService.getSchedulerChangeManagements()
+ .then(function(response) {
+ vm.pendingChangeManagements = response.data;
+ _.forEach(vm.pendingChangeManagements, function(changeManagement) {
+ var callbackData = _.filter(changeManagement.scheduleRequest.domainData, {name: "CallbackData"});
+ if(callbackData) {
+ var parsedModel = {};
+ try {
+ parsedModel = JSON.parse(callbackData[0].value);
+ } catch(exception) {
+ $log.error(exception);
+ }
+
+ changeManagement.workflow = parsedModel.requestType || 'No workflow';
+ }
+ });
+ })
+ .catch(function(error) {
+ $log.error(error);
+ });
+ };
+
+ vm.createNewChange = function() {
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/new-change-management/new-change-management.html',
+ controller: 'newChangeManagementModalController',
+ controllerAs: 'vm',
+ resolve: {}
+ });
+
+ modalInstance.result.then(function (result) {
+ console.log("This is the result of the new change management modal.", result);
+ });
+ };
+
+ vm.openScheduler = function() {
+ console.log("function for opening the scheduler app")
+ };
+
+ vm.searchChanges = function() {
+ console.log("function for searching changes: " + vm.searchChangesTerm)
+ };
+
+ vm.openFailedModal = function(jobInfo) {
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/failed-change-management/failed-change-management.html',
+ controller: 'changeManagementManualTasksController',
+ controllerAs: 'vm',
+ resolve: {
+ jobInfo: function () {
+ return jobInfo;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (result) {
+ console.log("This is the result of the failed change management modal.", result);
+ });
+ };
+
+ vm.openInProgressModal = function(jobInfo) {
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.html',
+ controller: 'changeManagementManualTasksController',
+ controllerAs: 'vm',
+ resolve: {
+ jobInfo: function () {
+ return jobInfo;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (result) {
+ console.log("This is the result of the in progress change management modal.", result);
+ });
+ };
+
+ vm.openAlertModal = function(jobInfo) {
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/alert-change-management/alert-change-management.html',
+ controller: 'changeManagementManualTasksController',
+ controllerAs: 'vm',
+ resolve: {
+ jobInfo: function () {
+ return jobInfo;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (result) {
+ console.log("This is the result of the alert change management modal.", result);
+ });
+ };
+
+ vm.openPendingModal = function(jobInfo) {
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/pending-change-management/pending-change-management.html',
+ controller: 'changeManagementManualTasksController',
+ controllerAs: 'vm',
+ resolve: {
+ jobInfo: function () {
+ return jobInfo;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (result) {
+ console.log("This is the result of the pending change management modal.", result);
+ });
+ };
+
+ init();
+ }
+})(); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/directives/angularjs-datetime-picker.js b/vid-app-common/src/main/webapp/app/vid/scripts/directives/angularjs-datetime-picker.js
new file mode 100644
index 000000000..b80b4cdae
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/directives/angularjs-datetime-picker.js
@@ -0,0 +1,361 @@
+
+ 'use strict';
+
+
+
+ var getTimezoneOffset = function(date) {
+ (typeof date == 'string') && (date = new Date(date));
+ var jan = new Date(date.getFullYear(), 0, 1);
+ var jul = new Date(date.getFullYear(), 6, 1);
+ var stdTimezoneOffset = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
+ var isDST = date.getTimezoneOffset() < stdTimezoneOffset;
+ var offset = isDST ? stdTimezoneOffset - 60 : stdTimezoneOffset;
+ var diff = offset >=0 ? '-' : '+';
+ return diff +
+ ("0"+ (offset / 60)).slice(-2) + ':' +
+ ("0"+ (offset % 60)).slice(-2);
+ };
+
+ var DatetimePicker = function($compile, $document, $controller){
+ var datetimePickerCtrl = $controller('DatetimePickerCtrl'); //directive controller
+ return {
+ open: function(options) {
+ datetimePickerCtrl.openDatetimePicker(options);
+ },
+ close: function() {
+ datetimePickerCtrl.closeDatetimePicker();
+ }
+ };
+ };
+ DatetimePicker.$inject = ['$compile', '$document', '$controller'];
+ appDS2.factory('DatetimePicker', DatetimePicker);
+
+ var DatetimePickerCtrl = function($compile, $document) {
+ var datetimePickerEl;
+ var _this = this;
+ var removeEl = function(el) {
+ el && el.remove();
+ $document[0].body.removeEventListener('click', _this.closeDatetimePicker);
+ };
+
+ this.openDatetimePicker = function(options) {
+ this.closeDatetimePicker();
+ var div = angular.element('<div datetime-picker-popup ng-cloak></div>');
+ options.dateFormat && div.attr('date-format', options.dateFormat);
+ options.ngModel && div.attr('ng-model', options.ngModel);
+ options.year && div.attr('year', parseInt(options.year));
+ options.month && div.attr('month', parseInt(options.month));
+ options.day && div.attr('day', parseInt(options.day));
+ options.hour && div.attr('hour', parseInt(options.hour));
+ options.minute && div.attr('minute', parseInt(options.minute));
+ if (options.dateOnly === '' || options.dateOnly === true) {
+ div.attr('date-only', 'true');
+ }
+ if (options.closeOnSelect === 'false') {
+ div.attr('close-on-select', 'false');
+ }
+
+ var triggerEl = options.triggerEl;
+ options.scope = options.scope || angular.element(triggerEl).scope();
+ datetimePickerEl = $compile(div)(options.scope)[0];
+ datetimePickerEl.triggerEl = options.triggerEl;
+
+ $document[0].body.appendChild(datetimePickerEl);
+
+ //show datetimePicker below triggerEl
+ var bcr = triggerEl.getBoundingClientRect();
+
+
+ options.scope.$apply();
+
+ var datePickerElBcr = datetimePickerEl.getBoundingClientRect();
+
+ datetimePickerEl.style.position='absolute';
+ if(bcr.width > datePickerElBcr.width){
+ datetimePickerEl.style.left= (bcr.left + bcr.width - datePickerElBcr.width + window.scrollX) + 'px';
+ } else {
+ datetimePickerEl.style.left= (bcr.left + window.scrollX) + 'px';
+ }
+
+ if (bcr.top < 300 || window.innerHeight - bcr.bottom > 300) {
+ datetimePickerEl.style.top = (bcr.bottom + window.scrollY) + 'px';
+ } else {
+ datetimePickerEl.style.top = (bcr.top - datePickerElBcr.height + window.scrollY) + 'px';
+ }
+
+ $document[0].body.addEventListener('click', this.closeDatetimePicker);
+ };
+
+ this.closeDatetimePicker = function(evt) {
+ var target = evt && evt.target;
+ var popupEl = $document[0].querySelector('div[datetime-picker-popup]');
+ if (evt && target) {
+ if (target.hasAttribute('datetime-picker')) { // element with datetimePicker behaviour
+ // do nothing
+ } else if (popupEl && popupEl.contains(target)) { // datetimePicker itself
+ // do nothing
+ } else {
+ removeEl(popupEl);
+ }
+ } else {
+ removeEl(popupEl);
+ }
+ }
+ };
+ DatetimePickerCtrl.$inject = ['$compile', '$document'];
+ appDS2.controller('DatetimePickerCtrl', DatetimePickerCtrl);
+
+ var tmpl = [
+ '<div class="angularjs-datetime-picker">' ,
+ ' <div class="adp-month">',
+ ' <button type="button" class="adp-prev" ng-click="addMonth(-1)">&laquo;</button>',
+ ' <span title="{{months[mv.month].fullName}}">{{months[mv.month].shortName}}</span> {{mv.year}}',
+ ' <button type="button" class="adp-next" ng-click="addMonth(1)">&raquo;</button>',
+ ' </div>',
+ ' <div class="adp-days" ng-click="setDate($event)">',
+ ' <div class="adp-day-of-week" ng-repeat="dayOfWeek in ::daysOfWeek" title="{{dayOfWeek.fullName}}">{{::dayOfWeek.firstLetter}}</div>',
+ ' <div class="adp-day" ng-show="mv.leadingDays.length < 7" ng-repeat="day in mv.leadingDays">{{::day}}</div>',
+ ' <div class="adp-day selectable" ng-repeat="day in mv.days" ',
+ ' today="{{today}}" d2="{{mv.year + \'-\' + (mv.month + 1) + \'-\' + day}}"',
+ ' ng-class="{',
+ ' selected: (day == selectedDay),',
+ ' today: (today == (mv.year + \'-\' + (mv.month + 1) + \'-\' + day)),',
+ ' weekend: (mv.leadingDays.length + day)%7 == 1 || (mv.leadingDays.length + day)%7 == 0',
+ ' }">',
+ ' {{::day}}',
+ ' </div>',
+ ' <div class="adp-day" ng-show="mv.trailingDays.length < 7" ng-repeat="day in mv.trailingDays">{{::day}}</div>',
+ ' </div>',
+ ' <div class="adp-days" id="adp-time"> ',
+ ' <label class="timeLabel">Time:</label> <span class="timeValue">{{("0"+inputHour).slice(-2)}} : {{("0"+inputMinute).slice(-2)}}</span><br/>',
+ ' <label class="hourLabel">Hour:</label> <input class="hourInput" type="range" min="0" max="23" ng-model="inputHour" ng-change="updateNgModel()" />',
+ ' <label class="minutesLabel">Min:</label> <input class="minutesInput" type="range" min="0" max="59" ng-model="inputMinute" ng-change="updateNgModel()"/> ',
+ ' </div>',
+ '</div>'].join("\n");
+
+ var datetimePickerPopup = function($locale, dateFilter){
+ var days, months, daysOfWeek, firstDayOfWeek;
+
+ var initVars = function() {
+ days =[], months=[]; daysOfWeek=[], firstDayOfWeek=0;
+ for (var i = 1; i <= 31; i++) {
+ days.push(i);
+ }
+
+ for (var i = 0; i < 12; i++) { //jshint ignore:line
+ months.push({
+ fullName: $locale.DATETIME_FORMATS.MONTH[i],
+ shortName: $locale.DATETIME_FORMATS.SHORTMONTH[i]
+ });
+ }
+
+ for (var i = 0; i < 7; i++) { //jshint ignore:line
+ var day = $locale.DATETIME_FORMATS.DAY[(i + firstDayOfWeek) % 7];
+
+ daysOfWeek.push({
+ fullName: day,
+ firstLetter: day.substr(0, 1)
+ });
+ }
+ firstDayOfWeek = 0;
+ };
+
+ var getMonthView = function(year, month) {
+ if (month>11) {
+ year++;
+ } else if (month < 0) {
+ year--;
+ }
+ month = (month + 12) % 12;
+ var firstDayOfMonth = new Date(year, month, 1),
+ lastDayOfMonth = new Date(year, month + 1, 0),
+ lastDayOfPreviousMonth = new Date(year, month, 0),
+ daysInMonth = lastDayOfMonth.getDate(),
+ daysInLastMonth = lastDayOfPreviousMonth.getDate(),
+ dayOfWeek = firstDayOfMonth.getDay(),
+ leadingDays = (dayOfWeek - firstDayOfWeek + 7) % 7 || 7, // Ensure there are always leading days to give context
+ trailingDays = days.slice(0, 6 * 7 - (leadingDays + daysInMonth));
+ if (trailingDays.length > 7) {
+ trailingDays = trailingDays.slice(0, trailingDays.length-7);
+ }
+
+ return {
+ year: year,
+ month: month,
+ days: days.slice(0, daysInMonth),
+ leadingDays: days.slice(- leadingDays - (31 - daysInLastMonth), daysInLastMonth),
+ trailingDays: trailingDays
+ };
+ };
+
+ var linkFunc = function(scope, element, attrs, ctrl) { //jshint ignore:line
+ initVars(); //initialize days, months, daysOfWeek, and firstDayOfWeek;
+ var dateFormat = attrs.dateFormat || 'short';
+ scope.months = months;
+ scope.daysOfWeek = daysOfWeek;
+ scope.inputHour;
+ scope.inputMinute;
+
+ if (scope.dateOnly === true){
+ element[0].querySelector('#adp-time').style.display = 'none';
+ }
+
+ scope.$applyAsync( function() {
+ ctrl.triggerEl = angular.element(element[0].triggerEl);
+ if (attrs.ngModel) { // need to parse date string
+ var dateStr = ''+ctrl.triggerEl.scope().$eval(attrs.ngModel);
+ if (dateStr) {
+ if (!dateStr.match(/[0-9]{2}:/)) { // if no time is given, add 00:00:00 at the end
+ dateStr += " 00:00:00";
+ }
+ dateStr = dateStr.replace(/([0-9]{2}-[0-9]{2})-([0-9]{4})/,'$2-$1'); //mm-dd-yyyy to yyyy-mm-dd
+ dateStr = dateStr.replace(/([\/-][0-9]{2,4})\ ([0-9]{2}\:[0-9]{2}\:)/,'$1T$2'); //reformat for FF
+ dateStr = dateStr.replace(/EDT|EST|CDT|CST|MDT|PDT|PST|UT|GMT/g,''); //remove timezone
+ dateStr = dateStr.replace(/\s*\(\)\s*/,''); //remove timezone
+ dateStr = dateStr.replace(/[\-\+][0-9]{2}:?[0-9]{2}$/,''); //remove timezone
+ dateStr += getTimezoneOffset(dateStr);
+ var d = new Date(dateStr);
+ scope.selectedDate = new Date(
+ d.getFullYear(),
+ d.getMonth(),
+ d.getDate(),
+ d.getHours(),
+ d.getMinutes(),
+ d.getSeconds()
+ );
+ }
+ }
+
+ if (!scope.selectedDate || isNaN(scope.selectedDate.getTime())) { // no predefined date
+ var today = new Date();
+ var year = scope.year || today.getFullYear();
+ var month = scope.month ? (scope.month-1) : today.getMonth();
+ var day = scope.day || today.getDate();
+ var hour = scope.hour || today.getHours();
+ var minute = scope.minute || today.getMinutes();
+ scope.selectedDate = new Date(year, month, day, hour, minute, 0);
+ }
+ scope.inputHour = scope.selectedDate.getHours();
+ scope.inputMinute = scope.selectedDate.getMinutes();
+
+ // Default to current year and month
+ scope.mv = getMonthView(scope.selectedDate.getFullYear(), scope.selectedDate.getMonth());
+ scope.today = dateFilter(new Date(), 'yyyy-M-d');
+ if (scope.mv.year == scope.selectedDate.getFullYear() && scope.mv.month == scope.selectedDate.getMonth()) {
+ scope.selectedDay = scope.selectedDate.getDate();
+ } else {
+ scope.selectedDay = null;
+ }
+ });
+
+/* disable previous months.not current months
+ scope.addMonth = function (amount) {
+ var today = new Date();
+ if((amount==-1) && (scope.mv.month==today.getMonth())){
+
+
+ }
+ else{
+
+ scope.mv = getMonthView(scope.mv.year, scope.mv.month + amount);
+ }
+ };*/
+
+ scope.addMonth = function (amount) {
+ scope.mv = getMonthView(scope.mv.year, scope.mv.month + amount);
+ };
+
+ scope.setDate = function (evt) {
+
+ var target = angular.element(evt.target)[0];
+ if (target.className.indexOf('selectable') !== -1) {
+ scope.updateNgModel(parseInt(target.innerHTML));
+ if (scope.closeOnSelect !== false) {
+ ctrl.closeDatetimePicker();
+ }
+ }
+ };
+
+ scope.updateNgModel = function(day) {
+ day = day ? day : scope.selectedDate.getDate();
+ scope.selectedDate = new Date(
+ scope.mv.year, scope.mv.month, day, scope.inputHour, scope.inputMinute, 0
+ );
+ scope.selectedDay = scope.selectedDate.getDate();
+ if (attrs.ngModel) {
+ //console.log('attrs.ngModel',attrs.ngModel);
+ var elScope = ctrl.triggerEl.scope(), dateValue;
+ if (elScope.$eval(attrs.ngModel) && elScope.$eval(attrs.ngModel).constructor.name === 'Date') {
+ dateValue = new Date(dateFilter(scope.selectedDate, dateFormat));
+ } else {
+ dateValue = dateFilter(scope.selectedDate, dateFormat);
+ }
+ elScope.$eval(attrs.ngModel + '= date', {date: dateValue}); // this line for have the date in the format of mm/dd/yyyy
+ // elScope.$eval(attrs.ngModel + '= date', {date: scope.selectedDate});// this line in the format of Thu Jul 20 2017 23:59:00 GMT-0400 (Eastern Daylight Time)
+ }
+ };
+
+ scope.$on('$destroy', ctrl.closeDatetimePicker);
+ };
+
+ return {
+ restrict: 'A',
+ template: tmpl,
+ controller: 'DatetimePickerCtrl',
+ replace: true,
+ scope: {
+ year: '=',
+ month: '=',
+ day: '=',
+ hour: '=',
+ minute: '=',
+ dateOnly: '=',
+ closeOnSelect: '=',
+ futureOnly:'='
+ },
+ link: linkFunc
+ };
+ };
+ datetimePickerPopup.$inject = ['$locale', 'dateFilter'];
+ appDS2.directive('datetimePickerPopup', datetimePickerPopup);
+
+ var datetimePicker = function($parse, DatetimePicker) {
+ return {
+ // An ngModel is required to get the controller argument
+ require: 'ngModel',
+ link: function(scope, element, attrs, ctrl) {
+ // Attach validation watcher
+ scope.$watch(attrs.ngModel, function(value) {
+ if( !value || value == '' ){
+ return;
+ }
+ // The value has already been cleaned by the above code
+ var date = new Date(value);
+ ctrl.$setValidity('date', !date? false : true);
+ var now = new Date();
+ if( attrs.hasOwnProperty('futureOnly') ){
+ ctrl.$setValidity('future-only', date < now? false : true);
+ }
+ });
+
+ element[0].addEventListener('click', function() {
+ DatetimePicker.open({
+ triggerEl: element[0],
+ dateFormat: attrs.dateFormat,
+ ngModel: attrs.ngModel,
+ year: attrs.year,
+ month: attrs.month,
+ day: attrs.day,
+ hour: attrs.hour,
+ minute: attrs.minute,
+ dateOnly: attrs.dateOnly,
+ futureOnly: attrs.futureOnly,
+ closeOnSelect: attrs.closeOnSelect
+ });
+ });
+ }
+ };
+ };
+ datetimePicker.$inject=['$parse', 'DatetimePicker'];
+ appDS2.directive('datetimePicker', datetimePicker);
+
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/filters/change-managements-by-statuses.filter.js b/vid-app-common/src/main/webapp/app/vid/scripts/filters/change-managements-by-statuses.filter.js
new file mode 100644
index 000000000..6f0ae2c69
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/filters/change-managements-by-statuses.filter.js
@@ -0,0 +1,22 @@
+(function () {
+ 'use strict';
+ appDS2.filter('changeManagementsByStatuses', [changeManagementsByStatuses]);
+
+ function changeManagementsByStatuses () {
+ return function(changeManagements, metadata) {
+ var result = [];
+ if(changeManagements && metadata && metadata.statuses) {
+ angular.forEach(changeManagements, function(changeManagement) {
+ angular.forEach(metadata.statuses, function(status) {
+ if(changeManagement.requestStatus.requestState === status) {
+ result.push(changeManagement);
+ return;
+ }
+ });
+ });
+ }
+
+ return result;
+ }
+ }
+})();
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/filters/date.filter.js b/vid-app-common/src/main/webapp/app/vid/scripts/filters/date.filter.js
new file mode 100644
index 000000000..3b2eb1836
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/filters/date.filter.js
@@ -0,0 +1,18 @@
+(function () {
+ 'use strict';
+ appDS2.filter('vidDate', ['$filter', vidDate]);
+
+ function vidDate($filter) {
+ var suffixes = ["th", "st", "nd", "rd"];
+ return function(input, format) {
+ if(input) {
+ var dtfilter = $filter('date')(input, format);
+ var day = parseInt($filter('date')(input, 'dd'));
+ var relevantDigits = (day < 30) ? day % 20 : day % 30;
+ var suffix = (relevantDigits <= 3) ? suffixes[relevantDigits] : suffixes[0];
+ return dtfilter.replace('oo', suffix);
+ }
+ return input;
+ };
+ }
+})();
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.css
new file mode 100644
index 000000000..316c2e46e
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.css
@@ -0,0 +1,3 @@
+.modal-header h3 {
+ border-bottom: 3px solid #ffb81c;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.html
new file mode 100644
index 000000000..bdc95c98e
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-change-management/alert-change-management.html
@@ -0,0 +1,12 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-change-management/new-change-management.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/alert-change-management/alert-change-management.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="alert-modal-header">On Hold</h3>
+ <span id="cancel" ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+</div>
+<div class="modal-body">
+ <span id="alert-modal-content">{{vm.content}}</span>
+</div>
+<div class="modal-footer">
+ <div ng-include="'app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html'"></div>
+</div>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.controller.js
new file mode 100644
index 000000000..2c5eabed9
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.controller.js
@@ -0,0 +1,33 @@
+(function () {
+ 'use strict';
+
+ appDS2.controller("alertNewSchedulerController", ["$uibModalInstance", "jobInfo", "MsoService", "COMPONENT",
+ "$log", alertNewSchedulerController]);
+
+ function alertNewSchedulerController($uibModalInstance, jobInfo, MsoService, COMPONENT, $log) {
+ var vm = this;
+
+ vm.manualTasks = [];
+ vm.MANUAL_TASKS = COMPONENT.MANUAL_TASKS;
+ var init = function() {
+ if (jobInfo) {
+ vm.content = jobInfo;
+ } else {
+ vm.content = "Successfully";
+ }
+
+
+
+ };
+
+
+
+
+
+ vm.close = function () {
+ $uibModalInstance.close();
+ };
+
+ init();
+ }
+})(); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.css
new file mode 100644
index 000000000..316c2e46e
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.css
@@ -0,0 +1,3 @@
+.modal-header h3 {
+ border-bottom: 3px solid #ffb81c;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.html
new file mode 100644
index 000000000..e6255cf36
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.html
@@ -0,0 +1,12 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-change-management/new-change-management.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/alert-change-management/alert-change-management.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="alert-modal-header">Response From Server</h3>
+ <span id="cancel" ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+</div>
+<div class="modal-body">
+ <span id="alert-modal-content">{{vm.content}}</span>
+</div>
+<div class="modal-footer">
+<!-- <div ng-include="'app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html'"></div> -->
+</div> \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.controller.js
new file mode 100644
index 000000000..91bac5697
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.controller.js
@@ -0,0 +1,56 @@
+(function () {
+ 'use strict';
+
+ appDS2.controller("changeManagementManualTasksController", ["$uibModalInstance", "jobInfo", "MsoService", "COMPONENT",
+ "$log", changeManagementManualTasksController]);
+
+ function changeManagementManualTasksController($uibModalInstance, jobInfo, MsoService, COMPONENT, $log) {
+ var vm = this;
+
+ vm.manualTasks = [];
+ vm.MANUAL_TASKS = COMPONENT.MANUAL_TASKS;
+ var init = function() {
+ if (jobInfo && jobInfo.details) {
+ vm.content = jobInfo.details;
+ } else {
+ vm.content = "The VNF change alerted due to unknown reason.";
+ }
+
+ loadAvailableTasks(jobInfo.job.requestId);
+
+ };
+
+ function loadAvailableTasks(requestId) {
+ MsoService.getManualTasks(requestId)
+ .then(function(response) {
+ vm.task = response.data[0];
+ vm.manualTasks = vm.task && vm.task.validResponses;
+ })
+ .catch(function(error) {
+ $log.error(error);
+ });
+ }
+
+ vm.completeTask = function(task) {
+ MsoService.completeTask(vm.task.taskId, task)
+ .then(function(response) {
+ vm.manualTasks = response.data;
+ $uibModalInstance.close(task + " action completed successfully.");
+ })
+ .catch(function(error) {
+ $uibModalInstance.close(task + " action failed.");
+ $log.error(error);
+ });
+ };
+
+ vm.close = function () {
+ $uibModalInstance.close();
+ };
+
+ vm.isTaskAvailable = function(task) {
+ return vm.manualTasks.includes(task);
+ };
+
+ init();
+ }
+})(); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html
new file mode 100644
index 000000000..687394156
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html
@@ -0,0 +1,7 @@
+<div class="pull-right">
+ <button ng-repeat="task in vm.manualTasks"
+ type="button" id="{{task}}-button" name="{{task}}" class="btn btn-primary"
+ ng-show="vm.isTaskAvailable(vm.MANUAL_TASKS[task])"
+ ng-click="vm.completeTask(vm.MANUAL_TASKS[task])">{{task.charAt(0).toUpperCase() + task.slice(1)}}</button>
+</div>
+
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.css
new file mode 100644
index 000000000..fb4a06c7b
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.css
@@ -0,0 +1,3 @@
+.modal-header h3 {
+ border-bottom: 3px solid #cf2a2a;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.html
new file mode 100644
index 000000000..0deaf93d2
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/failed-change-management/failed-change-management.html
@@ -0,0 +1,12 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-change-management/new-change-management.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/failed-change-management/failed-change-management.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="failed-modal-header">Failed</h3>
+ <span id="cancel" ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+</div>
+<div class="modal-body">
+ <span id="failed-modal-content">{{vm.content}}</span>
+</div>
+<div class="modal-footer">
+ <div ng-include="'app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html'"></div>
+</div>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.css
new file mode 100644
index 000000000..02a0df47e
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.css
@@ -0,0 +1,3 @@
+.modal-header h3 {
+ border-bottom: 3px solid #4ca90c;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.html
new file mode 100644
index 000000000..9b40db2a5
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.html
@@ -0,0 +1,12 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-change-management/new-change-management.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/in-progress-modal-management/in-progress-change-management.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="in-progress-modal-header">In Progress</h3>
+ <span id="cancel" ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+</div>
+<div class="modal-body">
+ <span id="in-progress-modal-content">{{vm.content}}</span>
+</div>
+<div class="modal-footer">
+ <div ng-include="'app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html'"></div>
+</div>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
new file mode 100644
index 000000000..14ca43b56
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.controller.js
@@ -0,0 +1,369 @@
+(function () {
+ 'use strict';
+
+ appDS2.controller("newChangeManagementModalController", ["$uibModalInstance", "$uibModal", "AaiService", "changeManagementService",
+ "$log", "$scope", "_", newChangeManagementModalController]);
+
+ function newChangeManagementModalController($uibModalInstance, $uibModal, AaiService, changeManagementService, $log, $scope, _) {
+ var vm = this;
+
+ var init = function () {
+ vm.changeManagement = {};
+
+ loadServicesCatalog();
+ registerVNFNamesWatcher();
+ vm.loadSubscribers();
+ };
+
+ var loadServicesCatalog = function () {
+ changeManagementService.getAllSDCServices()
+ .then(function (response) {
+ vm.SDCServicesCatalog = response.data;
+ })
+ .catch(function (error) {
+ $log.error(error);
+ })
+ };
+
+ var registerVNFNamesWatcher = function () {
+ $scope.$watch('vm.changeManagement.vnfNames', function (newVal, oldVal) {
+ if (!oldVal || newVal && newVal.length > oldVal.length) { //JUST THE LAST ONE ADDED
+ var newVNFName = _.last(vm.changeManagement.vnfNames);
+ if (oldVal) {
+ vm.changeManagement.vnfNames = oldVal;
+ vm.changeManagement.vnfNames.push(newVNFName);
+ }
+ if (newVNFName && newVNFName["service-instance-node"]) {
+ var availableVersions = [];
+ var services = _.filter(vm.SDCServicesCatalog.services,
+ {"invariantUUID": newVNFName["service-instance-node"][0].properties["model-invariant-id"]});
+
+ _.each(services, function (service) {
+ changeManagementService.getSDCService(service.uuid)
+ .then(function (response) {
+ _.each(response.data.vnfs, function (vnf) {
+ if (newVNFName["invariant-id"] === vnf.invariantUuid) {
+ availableVersions.push(extractVNFModel(vnf, response.data.service, newVNFName));
+ }
+ });
+ var versions = _.uniqBy(availableVersions, ['modelInfo.modelVersion']);
+ newVNFName.availableVersions = _.uniq(versions, response.data.service, true);
+ }).catch(function (error) {
+ $log.error(error);
+ });
+ });
+ }
+ }
+ }, true);
+ };
+
+ var extractVNFModel = function (csarVNF, sdcService, selectionVNF) {
+ var versionCsarData = {
+ vnfInstanceId: "",
+ vnfName: csarVNF.name,
+ modelInfo: {
+ modelType: "vnf",
+ modelInvariantId: csarVNF.invariantUuid,
+ modelVersionId: selectionVNF.modelVersionId,
+ modelName: csarVNF.name,
+ modelVersion: csarVNF.version,
+ modelCustomizationName: csarVNF.modelCustomizationName,
+ modelCustomizationId: csarVNF.customizationUuid
+ },
+ cloudConfiguration: {
+ lcpCloudRegionId: "mdt1",
+ tenantId: "88a6ca3ee0394ade9403f075db23167e"
+ },
+ requestInfo: {
+ source: "VID",
+ suppressRollback: false,
+ requestorId: "az2016"
+ },
+ relatedInstanceList: [
+ {
+ relatedInstance: {
+ instanceId: selectionVNF["service-instance-node"]["0"].properties['service-instance-id'],
+ modelInfo: {
+ modelType: "service",
+ modelInvariantId: selectionVNF["service-instance-node"]["0"].properties['model-invariant-id'],
+ modelVersionId: selectionVNF.modelVersionId,
+ modelName: sdcService.name,
+ modelVersion: sdcService.version,
+ modelCustomizationName: selectionVNF["service-instance-node"]["0"].properties['model-customization-name'], //TODO: Missing
+ modelCustomizationId: selectionVNF["service-instance-node"]["0"].properties['model-customization-id']
+ }
+ }
+ }
+ ],
+ requestParameters: {
+ usePreload: true
+ }
+ };
+
+ return versionCsarData;
+ };
+
+ vm.close = function () {
+ $uibModalInstance.close();
+ };
+
+ vm.schedule = function () {
+ $uibModalInstance.close(vm.changeManagement);
+
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/new-scheduler/new-scheduler.html',
+ controller: 'newSchedulerController',
+ controllerAs: 'vm',
+ resolve: {
+ changeManagement: function () {
+ return vm.changeManagement;
+ }
+ }
+ });
+
+ modalInstance.result.then(function (result) {
+ console.log("This is the result of the new change management modal.", result);
+ })
+ };
+
+ vm.loadSubscribers = function () {
+ vm.subscribers = [];
+ AaiService.getSubscribers(function (response) {
+ vm.subscribers = response;
+ });
+ };
+
+ vm.loadServiceTypes = function () {
+ vm.serviceTypes = [];
+
+ AaiService.getSubscriberServiceTypes(vm.changeManagement.subscriberId)
+ .then(function (response) {
+ vm.serviceTypes = response.data;
+ })
+ .catch(function (error) {
+ $log.error(error);
+ });
+ };
+
+ vm.loadVNFTypes = function () {
+ vm.vnfTypes = [];
+ vm.vnfTypesTemp = [];
+ vm.serviceInstances = [];
+
+ var instances = vm.changeManagement.serviceType["service-instances"]["service-instance"];
+ // var promiseArrOfGetVnfs = preparePromiseArrOfGetVnfs(instances);
+
+ vm.vnfs = [];
+
+ AaiService.getVnfsByCustomerIdAndServiceType(
+ vm.changeManagement.subscriberId,
+ vm.changeManagement.serviceType["service-type"]
+ ).then(function (response) {
+ var vnfsData = response.data.results;
+ if (vnfsData) {
+ for (var i = 0; i < vnfsData.length; i++) {
+ if (vnfsData[i]) {
+ const nodeType = vnfsData[i]['node-type'];
+ if (nodeType === "generic-vnf") {
+ _.forEach(vnfsData[i]['related-to'], function (node) {
+ if (node['node-type'] === 'vserver') {
+ vm.vnfs.push(vnfsData[i]);
+ }
+ })
+ } else if (nodeType === "service-instance") {
+ vm.serviceInstances.push(vnfsData[i]);
+ }
+ }
+ }
+
+ vm.vnfs = _.flattenDeep(
+ _.remove(vm.vnfs, function (vnf) {
+ var nfRole = vnf.properties['nf-role'];
+ if (nfRole !== undefined) {
+ return nfRole !== 'null' && nfRole !== '';
+ }
+ })
+ );
+
+ var filteredVnfs = _.uniqBy(vm.vnfs, function (vnf) {
+ return vnf.properties['nf-role'];
+ });
+
+ _.forEach(filteredVnfs, function (vnf) {
+ vm.vnfTypes.push(vnf.properties['nf-role'])
+ });
+ }
+ }
+ );
+ };
+
+ vm.loadVNFVersions = function () {
+ vm.fromVNFVersions = [];
+ vm.serviceInstancesToGetVersions = [];
+ var versions = [];
+ _.forEach(vm.vnfs, function (vnf) {
+ if (vnf.properties['nf-role'] === vm.changeManagement['vnfType']) {
+
+ vm.serviceInstancesToGetVersions.push(vnf);
+
+ versions.push(vnf.properties["model-invariant-id"]);
+
+
+ }
+ });
+
+ AaiService.getVnfVersionsByInvariantId(versions).then(function (response) {
+ if (response.data) {
+ var key = response.data.model["0"]["model-invariant-id"];
+ var value = response.data.model["0"]["model-vers"]["model-ver"]["0"]["model-version"];
+ var element = {"key": key, "value": value};
+ vm.fromVNFVersions.push(element);
+ }
+ //TODO promise all and call the new api to get the versions.
+ // vm.fromVNFVersions.push(response.data.model["0"]["model-vers"]["model-ver"]["0"]["model-version"]);
+ // if(vm.serviceInstancesToGetVersions.length > 0){
+ //
+ // var promiseArrOfGetVnfs = preparePromiseArrOfGetVersions('a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb');
+ //
+ // Promise.all(promiseArrOfGetVnfs).then(function (allData) {
+ // vm.vnfs = _.flattenDeep(_.without(allData, null));
+ // var filteredVnfs = _.sortedUniqBy(vm.vnfs, function (vnf) {
+ // return vnf.properties.vnfType;
+ // });
+ //
+ // _.forEach(filteredVnfs, function (vnf) {
+ // vm.vnfTypes.push(vnf.properties.vnfType)
+ // });
+ //
+ // }).catch(function (error) {
+ // $log(error);
+ // });
+ // }
+ })
+ // debugger;
+
+ };
+
+ // function preparePromiseArrOfGetVersions(serviceInstances) {
+ // var promiseArr = [];
+ // for (var i = 0; i < serviceInstances.length; i++) {
+ // var modelInvariantId = serviceInstances[i].properties["model-invariant-id"];
+ // promiseArr.push(
+ // getVnfs(modelInvariantId)
+ // );
+ // }
+ // return promiseArr;
+ // }
+
+ function getVnfs(modelInvariantId) {
+ return new Promise(function (resolve, reject) {
+ AaiService.getVnfVersionsByInvariantId(modelInvariantId)
+ .then(function (response) {
+ if (response.data.httpCode !== null &&
+ response.data.httpCode === 200) {
+ var vnfsData = response.data.t.results;
+ for (var i = 0; i < vnfsData.length; i++) {
+ if (vnfsData[i]) {
+ if (vnfsData[i].nodeType === "generic-vnf") {
+ resolve(vnfsData[i]);
+ } else if (vnfsData[i].nodeType === "service-instance") {
+ vm.serviceInstances.push(vnfsData[i]);
+ }
+ }
+ }
+ resolve(null);
+ }
+ resolve(null);
+ })
+ .catch(function (error) {
+ reject(error);
+ });
+ });
+ }
+
+ vm.loadVNFNames = function () {
+ vm.vnfNames = [];
+
+ _.forEach(vm.vnfs, function (vnf) {
+
+ if (vnf.properties['nf-role'] === vm.changeManagement.vnfType) {
+ var vServer = {};
+
+ _.forEach(vnf['related-to'], function (node) {
+ if (node['node-type'] === 'vserver') {
+ vServer = extractLcpRegionIdAndTenantId(node.url);
+ }
+ });
+
+ vm.vnfNames.push({
+ "id": vnf.properties["vnf-id"],
+ "name": vnf.properties["vnf-name"],
+ "invariant-id": vnf.properties["model-invariant-id"],
+ "service-instance-node": _.filter(vm.serviceInstances, {id: vnf["related-to"][0].id}),
+ "modelVersionId": vnf.properties["model-version-id"],
+ "properties": vnf.properties,
+ 'cloudConfiguration': vServer,
+ "relatedTo": vnf['related-to']
+ });
+ }
+ });
+ };
+
+ function extractLcpRegionIdAndTenantId(url) {
+
+ var cloudConfiguration = {
+ lcpCloudRegionId: '',
+ tenantId: ''
+ };
+
+ var splitedUrlByDash = _.split(url, '/', 100);
+
+ cloudConfiguration.lcpCloudRegionId = splitedUrlByDash[7];
+ cloudConfiguration.tenantId = splitedUrlByDash[10];
+
+ return cloudConfiguration;
+ };
+
+ vm.loadWorkFlows = function () {
+ var vnfs = [];
+ angular.forEach(vm.changeManagement.vnfNames, function (vnfName) {
+ vnfs.push(vnfName.name)
+ });
+
+ //TODO: When we'll have the mappings, use the backend call to get the workflows
+ // changeManagementService.getWorkflows(vnfs)
+ // .then(function(response) {
+ // vm.workflows = response.data;
+ // })
+ // .catch(function(error) {
+ // $log.error(error);
+ // });
+
+ vm.workflows = ["Update", "Replace"];
+ };
+
+ //Must be $scope because we bind to the onchange of the html (cannot attached to vm variable).
+ $scope.selectFileForVNFName = function (fileInput) {
+ if (fileInput && fileInput.id) {
+ var vnfName = _.filter(vm.changeManagement.vnfNames, {"invariant-id": fileInput.id});
+ var file = fileInput.files[0];
+ var fileReader = new FileReader();
+ fileReader.onload = function (load) {
+ try {
+ var lines = load.target.result;
+ vnfName[0].selectedFile = JSON.parse(lines);
+ } catch (error) {
+ $log.error(error);
+ }
+ };
+ fileReader.readAsText(file);
+ }
+ };
+
+ vm.selectVersionForVNFName = function (vnfName) {
+ console.log("Will add version for selected vnf name: " + vnfName.name);
+ };
+
+ init();
+ }
+})(); \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css
new file mode 100644
index 000000000..9d270987a
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.css
@@ -0,0 +1,130 @@
+.btn-white {
+ font-family: "Open Sans";
+ border-radius: 2px;
+ border: 1px solid #d8d8d8;
+ background-color: #ffffff;
+ width: 94px;
+ height: 30px;
+ color: #5a5a5a;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 36px;
+ text-align: center;
+ padding: 4px 12px !important;
+}
+
+.btn-primary {
+ font-family: "Open Sans";
+ border-radius: 2px;
+ border: 1px solid #0091c8;
+ background-color: #009fdb;
+ width: 94px;
+ height: 30px;
+ color: #ffffff;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 36px;
+ text-align: center;
+ padding: 4px 12px !important;
+}
+
+.modal-header {
+ border: none!important;
+ padding: 15px 15px 0px 15px!important;
+}
+
+.modal-header h3 {
+ font-family: "Open Sans";
+ color: #191919;
+ font-size: 22px;
+ font-weight: 300;
+ line-height: 16px;
+ padding-bottom: 20px;
+ border-bottom: 3px solid #009fdb;
+
+}
+
+.control-label {
+ font-family: "Open Sans";
+ color: #5a5a5a;
+ font-size: 13px;
+ font-weight: 400;
+}
+
+.modal-footer {
+ background-color: #eaeaea;
+}
+
+.modal-dialog {
+ width: 587px;
+ border-radius: 8px;
+}
+
+.modal-content {
+ width: 587px;
+ border-radius: 8px;
+ background-color: #ffffff;
+}
+
+button.dropdown-toggle {
+ text-align: left;
+}
+
+button[disabled].dropdown-toggle {
+ opacity: 1;
+ cursor: not-allowed;
+ background-color: #eee;
+ border: 1px solid #aaa;
+ color: #a0a0a0;
+}
+
+multiselect[disabled] {
+ cursor: not-allowed;
+}
+
+a.item-unselected:before {
+ font-family: "icomoon"!important;
+ content: "\e90c";
+ color: #4ca90c;
+}
+
+.modal-close {
+ margin: -40px 5px 0 0;
+ color: #5a5a5a;
+ font-size: 20px;
+ cursor: pointer;
+}
+
+.vnf-versions-container .table {
+ position: relative;
+ background-color: #f8f8f8;
+ background-clip: padding-box;
+ border-radius: 6px;
+ outline: 0;
+}
+
+.vnf-versions-name {
+ padding-top: 6px;
+ font-family: "Open Sans";
+ position: absolute;
+}
+
+.vnf-versions-select-as-text {
+ font-family: "Open Sans";
+ appearance: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ border: none;
+ overflow:hidden;
+ background-color: #f8f8f8;
+ height: 31px;
+}
+
+.vnf-files-select {
+ z-index: 999;
+ opacity: 0.0;
+ position: absolute;
+ width: 23%;
+ cursor: pointer;
+ height:100%;
+}
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html
new file mode 100644
index 000000000..71c7eb331
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-change-management/new-change-management.html
@@ -0,0 +1,68 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-change-management/new-change-management.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">New VNF Change</h3>
+ <span ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+</div>
+<form name="newChangeManagement" ng-submit="vm.schedule()">
+ <div class="modal-body">
+ <div class="form-group">
+ <label class="control-label">Subscriber</label>
+ <select class="form-control" ng-model="vm.changeManagement.subscriberId" ng-change="vm.loadServiceTypes()" name="subscriber" id="subscriber" data-tests-id="subscriberName" required>
+ <option value="" disabled>Select subscriber</option>
+ <option data-tests-id="subscriberNameOption" ng-repeat="item in vm.subscribers" ng-value="item['global-customer-id']">{{item['subscriber-name']}}</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <label class="control-label">Service type</label>
+ <select class="form-control" ng-model="vm.changeManagement.serviceType" ng-change="vm.loadVNFTypes()" name="serviceType" id="serviceType" ng-options="item['service-type'] for item in vm.serviceTypes" required data-ng-disabled="newChangeManagement.subscriber.$pristine">
+ <option value="" disabled>Select service type</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <label class="control-label">VNF type</label>
+ <select class="form-control" ng-model="vm.changeManagement.vnfType" ng-change="vm.loadVNFVersions()" name="vnfType" id="vnfType" ng-options="item for item in vm.vnfTypes" required data-ng-disabled="newChangeManagement.serviceType.$pristine">
+ <option value="" disabled>Select VNF type</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <label class="control-label">Source Version</label>
+ <select class="form-control" ng-model="vm.changeManagement.fromVNFVersion" ng-change="vm.loadVNFNames()" name="fromVNFVersion" id="fromVNFVersion" ng-options="item.key as item.value for item in vm.fromVNFVersions" required data-ng-disabled="newChangeManagement.vnfType.$pristine">
+ <option value="" disabled>Select from VNF version</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <label class="control-label">VNF name</label>
+ <multiselect ng-model="vm.changeManagement.vnfNames" ng-change="vm.loadWorkFlows()" name="vnfName" id="vnfName" options="vm.vnfNames" display-prop="name" id-prop="id" required data-ng-disabled="newChangeManagement.fromVNFVersion.$pristine"></multiselect>
+ </div>
+ <div ng-show="vm.changeManagement.vnfNames && vm.changeManagement.vnfNames.length > 0" class="form-group vnf-versions-container">
+ <table class="table table-bordered">
+ <tbody>
+ <tr ng-repeat="vnfName in vm.changeManagement.vnfNames">
+ <td class="col-md-6"><span class="vnf-versions-name">{{vnfName.name}}</span></td>
+ <td class="col-md-3">
+ <select ng-model="vnfName.version" ng-change="vm.selectVersionForVNFName(vnfName)" class="vnf-versions-select-as-text">
+ <option value="" disabled="" selected="selected">Select Target Version</option>
+ <option ng-repeat="version in vnfName.availableVersions">{{version.modelInfo.modelVersion}}</option>
+ </select>
+ </td>
+ <td class="col-md-3 vnf-versions-name">
+ <input ng-model="vnfName.filePath" onchange="angular.element(this).scope().selectFileForVNFName(this)" type="file" id="{{vnfName['invariant-id']}}" class="vnf-files-select" />
+ <span class="vnf-versions-name">Select File<span class="caret"></span></span></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div class="form-group">
+ <label class="control-label">Workflow</label>
+ <select class="form-control" ng-model="vm.changeManagement.workflow" name="workflow" id="workflow" ng-options="item for item in vm.workflows" required data-ng-disabled="newChangeManagement.vnfName.$pristine">
+ <option value="" disabled>Select workflow</option>
+ </select>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <div class="pull-right">
+ <button type="submit" id="submit" name="submit" class="btn btn-primary" data-ng-disabled="newChangeManagement.$invalid">Schedule</button>
+ <button type="button" id="cancel" name="cancel" class="btn btn-white" ng-click="vm.close()">Cancel</button>
+ </div>
+ </div>
+</form>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js
new file mode 100644
index 000000000..c8f44c715
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.controller.js
@@ -0,0 +1,455 @@
+(function () {
+ 'use strict';
+
+ appDS2.controller("newSchedulerController", ["$scope", "$uibModal", "$uibModalInstance", "AaiService", "SchedulerService", "_",
+ "$log", "changeManagement", "$timeout", "$interval", "$filter", "VIDCONFIGURATION", "changeManagementService", newSchedulerController]);
+
+ function newSchedulerController($scope, $uibModal, $uibModalInstance, AaiService, SchedulerService, _, $log, changeManagement, $timeout, $interval, $filter, VIDCONFIGURATION, changeManagementService) {
+ var vm = this;
+ var pollpromise;
+
+ var init = function () {
+ vm.scheduler = {};
+ vm.schedulingInfo = {};
+ var callbackData = extractChangeManagementCallbackDataStr(changeManagement);
+ vm.vnfObject = changeManagement;
+ vm.schedulerObj = {
+ domain: 'ChangeManagement',
+ scheduleId: '',
+ scheduleName: 'VnfUpgrade/DWF',
+ userId: '',
+ domainData: [{
+ 'WorkflowName': vm.scheduler.policy,
+ 'CallbackUrl': 'http://127.0.0.1:8989/scheduler/v1/loopbacktest/vid',
+ 'CallbackData': callbackData
+ }],
+
+ schedulingInfo: {
+ normalDurationInSeconds: '',
+ additionalDurationInSeconds: '',
+ concurrencyLimit: '',
+ policyId: '',
+ vnfDetails: [
+ {
+ groupId: "",
+ node: [],
+ changeWindow: [{
+ startTime: '',
+ endTime: ''
+ }]
+
+ }
+ ]
+ },
+
+ }
+ vm.schedulerObj1 = {
+ "domain": "ChangeManagement",
+ "scheduleName": "VnfUpgrade/DWF",
+ "userId": "su7376",
+ "domainData": [
+ {
+ "WorkflowName": "HEAT Stack Software Update for vNFs",
+ "CallbackUrl": "http://127.0.0.1:8989/scheduler/v1/loopbacktest/vid",
+ "CallbackData": "testing"
+ }
+ ],
+ "schedulingInfo": {
+ "normalDurationInSeconds": 60,
+ "additionalDurationInSeconds": 60,
+ "concurrencyLimit": 60,
+ "policyId": "SNIRO_CM_1707.Config_MS_Demo_TimeLimitAndVerticalTopology_zone_localTime.1.xml",
+ "vnfDetails": [
+ {
+ "groupId": "group1",
+ "node": ["satmo415vbc", "satmo455vbc"],
+ "changeWindow": [
+ {
+ "startTime": "2017-08-08T16:37:30.521Z",
+ "endTime": "2017-08-08T16:37:30.521Z"
+ }
+ ]
+ }
+ ]
+ }
+ };
+
+
+ vm.format = 'yyyy/MM/dd';
+ vm.todate = new Date();
+ vm.checkboxSelection = 'false';
+ vm.fromDate = '';
+ vm.toDate = '';
+ vm.timeSlots = [];
+
+ vm.changeManagement = {};
+
+ vm.subscribers = [];
+
+ AaiService.getSubscribers(function (response) {
+ vm.subscribers = response;
+ });
+
+ vm.serviceTypes = [];
+ AaiService.getServices(function (response) {
+ vm.serviceTypes = response.data.service;
+ });
+
+ changeManagementService.getWorkflows()
+ .then(function (response) {
+ vm.workflows = response.data;
+ })
+ .catch(function (error) {
+ $log.error(error);
+ });
+
+ //TODO: Get the VNF names from backend dynamically
+ vm.vnfNames = [];
+
+ //TODO: Get the VNF types from backend dynamically
+ vm.vnfTypes = [];
+
+ AaiService.getLoggedInUserID(function (response) {
+ vm.userID = response.data;
+ });
+ vm.policys = [];
+
+ var policyName = JSON.stringify({
+ policyName: "SNIRO_1710.*",
+ configAttributes: {
+ service: "PlacementOptimizationPolicy"
+ }
+ });
+ SchedulerService.getPolicyInfo(policyName, function (response) {
+ vm.policys = response.data.entity;
+ });
+ };
+
+ vm.radioSelections = function (test) {
+ if (vm.checkboxSelection == "true") {
+ vm.fromDate = '';
+ vm.toDate = ''
+ }
+ }
+ vm.close = function () {
+ $uibModalInstance.close();
+ };
+
+
+ function convertToSecs(number) {
+ var totalSecs;
+ if (vm.selectedOption === 'hours') {
+ totalSecs = number * 3600;
+
+ }
+ else if (vm.selectedOption === 'minutes') {
+ totalSecs = number * 60;
+ } else {
+ totalSecs = number;
+ }
+ return totalSecs;
+ }
+
+ vm.submit = function () {
+ vm.schedulingInfo = {
+ scheduleId: vm.schedulerID,
+ approvalDateTime: '2017-08-08T16:37:30.521Z',
+ approvalUserId: "sy6266",
+ approvalStatus: 'Accepted',
+ approvalType: 'Tier 2'
+ };
+
+ var approvalObj = JSON.stringify(vm.schedulingInfo);
+ SchedulerService.getSubmitForapprovedTimeslots(approvalObj, function (response) {
+ if (response.status == 200) {
+ openConfirmationModal("Successfully Sent for Approval");
+ }
+
+ });
+ };
+
+ vm.reject = function () {
+ vm.schedulingInfo = {
+ scheduleId: vm.schedulerID,
+ approvalDateTime: '2017-08-08T16:37:30.521Z',
+ approvalUserId: "sy6266",
+ approvalStatus: 'Rejected',
+ approvalType: 'Tier 2'
+ }
+
+ var approvalObj = JSON.stringify(vm.schedulingInfo)
+ SchedulerService.getSubmitForapprovedTimeslots(approvalObj, function (response) {
+ if (response.status == 200) {
+ openConfirmationModal("Successfully sent for Rejection");
+ }
+
+ });
+ };
+
+ vm.schedule = function (myForm) {
+ $scope.$watch('fromDate', validateDates(myForm));
+ $scope.$watch('toDate', validateDates(myForm));
+ if (myForm.$valid) {
+ sendSchedulerReq()
+ }
+ };
+
+
+ function sendSchedulerReq() {
+ var changeWindow = [{
+ startTime: '',
+ endTime: ''
+ }];
+ vm.timeSlots = [];
+ var fromDate = $filter('date')(new Date(vm.fromDate), "yyyy-MM-ddTHH:mmZ", "UTC");
+ var toDate = $filter('date')(new Date(vm.toDate), "yyyy-MM-ddTHH:mmZ", "UTC");
+
+ changeWindow[0].startTime = fromDate;
+ changeWindow[0].endTime = toDate;
+ vm.schedulerObj.userId = vm.userID;
+ vm.schedulerObj.domainData[0].WorkflowName = changeManagement.workflow;
+ vm.schedulerObj.schedulingInfo.normalDurationInSeconds = convertToSecs(vm.scheduler.duration);
+ vm.schedulerObj.schedulingInfo.additionalDurationInSeconds = convertToSecs(vm.scheduler.fallbackDuration);
+ vm.schedulerObj.schedulingInfo.concurrencyLimit = vm.scheduler.concurrency;
+ vm.schedulerObj.schedulingInfo.policyId = vm.scheduler.policy.policyName;
+ vm.schedulerObj.schedulingInfo['vnfDetails'][0].groupId = 'groupId';
+ vm.schedulerObj.schedulingInfo['vnfDetails'][0].node = getVnfData(changeManagement.vnfNames);
+
+ vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow = changeWindow;
+ if (vm.checkboxSelection == "true") { //When Scheduled now we remove the changeWindow
+ delete vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow;
+ }
+ vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow = changeWindow;
+ delete vm.schedulerObj.schedulingInfo['vnfDetails'][0].changeWindow;
+
+ var requestScheduler = JSON.stringify(vm.schedulerObj);
+ console.log(requestScheduler);
+ SchedulerService.getStatusSchedulerId(requestScheduler, function (response) {
+ vm.schedulerID = response.data.uuid;
+ vm.isSpinnerVisible = true;
+ if (vm.schedulerID) {
+ var scheduledID = JSON.stringify({scheduleId: vm.schedulerID});
+ seviceCallToGetTimeSlots();
+ }
+ });
+ }
+
+ function seviceCallToGetTimeSlots() {
+
+ SchedulerService.getTimeSotsForSchedulerId(vm.schedulerID, function (response) {
+ if (vm.checkboxSelection == "false") {
+ if (response.data.entity.schedule) {
+ var scheduleColl = JSON.parse(response.data.entity.schedule);
+ if (scheduleColl.length > 0) {
+ vm.timeSlots = scheduleColl;
+ vm.isSpinnerVisible = false;
+ hasvaluereturnd = false;
+ $scope.stopPoll();
+ openConfirmationModal(response.data.entity.scheduleId + " Successfully Returned TimeSlots.");
+ }
+
+ }
+ else {
+ if (vm.timeSlots.length == 0 && hasthresholdreached == false) {
+ var polltime = VIDCONFIGURATION.SCHEDULER_POLLING_INTERVAL_MSECS;
+ pollpromise = poll(polltime, function () {
+ if (vm.timeSlots.length == 0) {
+ hasvaluereturnd = true;
+ seviceCallToGetTimeSlots()
+ }
+ else {
+ hasvaluereturnd = false;
+ }
+
+ });
+
+ } else {
+ openConfirmationModal("Timeout error.")
+ }
+ }
+
+ }
+ else {
+ if (response.data.entity) {
+ vm.isSpinnerVisible = false;
+ openConfirmationModal(response.data.entity.scheduleId + " Successfully Ready for Schedule.")
+ }
+ }
+
+ });
+
+ }
+
+ function openConfirmationModal(jobInfo) {
+ var modalInstance = $uibModal.open({
+ templateUrl: 'app/vid/scripts/modals/alert-new-scheduler/alert-new-scheduler.html',
+ controller: 'alertNewSchedulerController',
+ controllerAs: 'vm',
+ resolve: {
+ jobInfo: function () {
+ return jobInfo;
+ }
+ }
+ });
+ }
+
+ var hasvaluereturnd = true; // Flag to check
+ var hasthresholdreached = false;
+ var thresholdvalue = VIDCONFIGURATION.SCHEDULER_MAX_POLLS; // interval threshold value
+
+ function poll(interval, callback) {
+ return $interval(function () {
+ if (hasvaluereturnd) { //check flag before start new call
+ callback(hasvaluereturnd);
+ }
+
+ thresholdvalue = thresholdvalue - 1; //Decrease threshold value
+ if (thresholdvalue == 0) {
+ $scope.stopPoll(); // Stop $interval if it reaches to threshold
+ }
+ }, interval)
+ }
+
+
+// stop interval.
+ $scope.stopPoll = function () {
+ $interval.cancel(pollpromise);
+ thresholdvalue = 0; //reset all flags.
+ hasvaluereturnd = false;
+ hasthresholdreached = true;
+ vm.isSpinnerVisible = false;
+ }
+
+ function getVnfData(arrColl) {
+ var vnfcolletion = [];
+
+ for (var i = 0; i < arrColl.length; i++) {
+ vnfcolletion.push(arrColl[i].name);
+ }
+
+ return vnfcolletion
+ }
+
+ function validateDates(form) {
+ if (vm.checkboxSelection == "false") {
+
+ if (form.startDate.$error.invalidDate || form.endDate.$error.invalidDate) {
+ form.startDate.$setValidity("endBeforeStart", true); //already invalid (per validDate directive)
+ } else {
+ //depending on whether the user used the date picker or typed it, this will be different (text or date type).
+ //creating a new date object takes care of that.
+ var endDate = new Date(vm.toDate);
+ var startDate = new Date(vm.fromDate);
+ form.startDate.$setValidity("endBeforeStart", endDate >= startDate);
+ }
+ }
+ }
+
+
+ function extractChangeManagementCallbackDataStr(changeManagement) {
+ var result = {};
+
+ result.requestType = changeManagement.workflow;
+ result.requestDetails = [];
+
+ _.forEach(changeManagement.vnfNames, function (vnf) {
+
+ var data = {
+ vnfName: vnf.name,
+ vnfInstanceId: vnf.id,
+ modelInfo: {
+ modelType: 'vnf',
+ modelInvariantId: vnf.properties['model-invariant-id'],
+ modelVersionId: vnf.modelVersionId,
+ modelName: vnf.properties['vnf-name'],
+ modelVersion: vnf.version,
+ modelCustomizationName: vnf.properties['model-customization-name'],
+ modelCustomizationId: vnf.properties['model-customization-id']
+ },
+ cloudConfiguration: {
+ lcpCloudRegionId: vnf.availableVersions[0].cloudConfiguration.lcpCloudRegionId,
+ tenantId: vnf.availableVersions[0].cloudConfiguration.tenantId
+ },
+ requestInfo: {
+ source: vnf.availableVersions[0].requestInfo.source,
+ suppressRollback: vnf.availableVersions[0].requestInfo.suppressRollback,
+ requestorId: vnf.availableVersions[0].requestInfo.requestorId
+ },
+ relatedInstanceList: [],
+ requestParameters: {
+ usePreload: vnf.availableVersions[0].requestParameters.usePreload
+ }
+ };
+
+ var serviceInstanceId = '';
+ _.forEach(vnf['service-instance-node'], function (instanceNode) {
+ if(instanceNode['node-type'] === 'service-instance'){
+ serviceInstanceId = instanceNode.properties['service-instance-id'];
+ }
+ });
+
+
+ _.forEach(vnf.availableVersions[0].relatedInstanceList, function (related) {
+
+ var rel = related.relatedInstance;
+
+ var relatedInstance = {
+ instanceId: serviceInstanceId,
+ modelInfo: {
+ modelType: rel.modelInfo.modelType,
+ modelInvariantId: rel.modelInfo.modelInvariantId,
+ modelVersionId: rel.modelInfo.modelVersionId,
+ modelName: rel.modelInfo.modelName,
+ modelVersion: rel.modelInfo.modelVersion,
+ modelCustomizationName: rel.modelInfo.modelCustomizationName,
+ modelCustomizationId: rel.modelInfo.modelCustomizationId
+ }
+ };
+
+ if (rel.vnfInstanceId)
+ relatedInstance.instanceId = rel.vnfInstanceId;
+
+ data.relatedInstanceList.push({relatedInstance: relatedInstance});
+ });
+
+
+ result.requestDetails.push(data);
+ }
+ );
+
+
+ // _.forEach(changeManagement.vnfNames, function (vnfName) {
+ // if (vnfName && vnfName.version) {
+ // if (vnfName.selectedFile) {
+ // vnfName.version.requestParameters.userParams = vnfName.selectedFile;
+ // }
+ // result.requestDetails.push(vnfName.version)
+ // }
+ // });
+
+ return JSON.stringify(result);
+ }
+
+ init();
+ };
+
+ appDS2.directive('validDate', function () {
+ return {
+ restrict: 'A',
+ require: 'ngModel',
+ link: function (scope, element, attrs, control) {
+ control.$parsers.push(function (viewValue) {
+ var newDate = model.$viewValue;
+ control.$setValidity("invalidDate", true);
+ if (typeof newDate === "object" || newDate == "") return newDate; // pass through if we clicked date from popup
+ if (!newDate.match(/^\d{1,2}\/\d{1,2}\/((\d{2})|(\d{4}))$/))
+ control.$setValidity("invalidDate", false);
+ return viewValue;
+ });
+ }
+ };
+ })
+
+
+})();
+
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css
new file mode 100644
index 000000000..8da5c55c5
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.css
@@ -0,0 +1,145 @@
+.btn-white {
+ font-family: OpenSans;
+ border-radius: 2px;
+ border: 1px solid #d8d8d8;
+ background-color: #ffffff;
+ width: 94px;
+ height: 30px;
+ color: #5a5a5a;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 36px;
+ text-align: center;
+}
+
+.btn-primary {
+ font-family: OpenSans;
+ border-radius: 2px;
+ border: 1px solid #0091c8;
+ background-color: #009fdb;
+ width: 94px;
+ height: 30px;
+ color: #ffffff;
+ font-size: 13px;
+ font-weight: 400;
+ line-height: 36px;
+ text-align: center;
+}
+
+.modal-header {
+ border: none!important;
+ padding: 15px 15px 0px 15px!important;
+}
+
+.modal-header h3 {
+ font-family: OpenSans;
+ color: #5a5a5a;
+ font-size: 22px;
+ font-weight: 300;
+ line-height: 16px;
+ padding-bottom: 20px;
+ border-bottom: 3px solid #009fdb;
+
+}
+
+.modal-footer {
+ background-color: #eaeaea;
+}
+
+.modal-dialog {
+ width: 587px;
+ border-radius: 8px;
+}
+
+.modal-content {
+ width: 587px;
+ border-radius: 8px;
+ background-color: #ffffff;
+}
+.label-font{
+ font-size: 1em;
+}
+.calender-icon{
+ background-image: url(../../../../../app/fusion/external/ebz/images/Calendar.svg);
+ background-repeat:no-repeat;
+ background-position:98%;
+ border-radius: 6px;
+ border: 1px solid #888;
+ color: #444;
+ font-family: clearview_att_regular;
+ width: 100%;
+ outline: 0;
+ padding: 7px 10px;
+ text-transform: none;
+ z-index: 0;
+ height: 40px;
+ position: relative;
+
+}
+
+input.calender-icon:focus{
+ background-image: url(../../../../../app/fusion/external/ebz/images/Calendar_blue.svg);
+ background-repeat:no-repeat;
+}
+
+
+
+.timeslots-content{
+ margin-top: 0px;
+ margin-bottom: 0px;
+ height: 10em;
+}
+.find-block{
+ float:5em;
+}
+.timeslots-block{
+/* margin-top: 1em; */
+ height: 85px;
+ }
+ .policy-combo{
+ background-image: none;
+ }
+
+ div[ng-controller=newSchedulerController] .schedulerVisible {
+ visibility: visible;
+}
+div[ng-controller=newSchedulerController] .schedulerHidden {
+ visibility: hidden;
+}
+
+.table {
+ border: 1px solid #eaeaea;
+ box-sizing: border-box;
+ background-color: #ffffff;
+ box-shadow: 0px 2px 7px 0px rgba(34, 31, 31, 0.17);
+ font-family: OpenSans;
+ color: #5a5a5a;
+ font-size: 14px;
+ font-weight: 400;
+}
+.table>thead {
+ background-color: #d2d2d2;
+ font-family: OpenSans;
+ color: #191919;
+ font-size: 13px;
+ font-weight: 600;
+ line-height: 40px;
+}
+
+.table-headline-row {
+ font-family: OpenSans;
+ color: #5a5a5a;
+ font-size: 14px;
+ font-weight: 600;
+ background-color: #eaeaea;
+ box-shadow: 0px 1px 1px 0px rgba(34, 31, 31, 0.19);
+}
+
+.table-bordered{border:1px solid #eaeaea;}
+.table-bordered>tbody>tr>td,
+.table-bordered>tbody>tr>th,
+.table-bordered>tfoot>tr>td,
+.table-bordered>tfoot>tr>th,
+.table-bordered>thead>tr>td,
+.table-bordered>thead>tr>th{border:1px solid #eaeaea;}
+
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html
new file mode 100644
index 000000000..498ff2ec4
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/new-scheduler/new-scheduler.html
@@ -0,0 +1,101 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-scheduler/new-scheduler.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="modal-title">Scheduler Change</h3>
+</div>
+<form name="newschedulermodalForm" ng-submit="vm.schedule(newschedulermodalForm)">
+ <div class="modal-body">
+
+ <div class="form-group" >
+ <label><input type="radio" ng-model="vm.checkboxSelection" ng-change="vm.radioSelections()" value="true">Now</label>
+ <label><input type="radio" ng-model="vm.checkboxSelection" ng-change="vm.radioSelections()" value="false">Range</label>
+ </div>
+<!-- <div class="form-group"> -->
+<!-- <input type="radio" ng-model="checkboxSelection" value="false" ><label>Range</label> -->
+<!-- </div> -->
+
+
+ <div class="form-group" >
+ <label class="control-label">From Date</label>
+ <input ng-disabled="(vm.checkboxSelection=='true')? true:false" valid-date name="startDate" ng-model="vm.fromDate" id="startDate" datetime-picker ng-required="false" hour="23" minute='59' class="calender-icon"/>
+
+ </div>
+ <div class="form-group" >
+ <label class="control-label">To Date</label>
+ <input ng-disabled="(vm.checkboxSelection=='true')? true:false" valid-date name="endDate" ng-model="vm.toDate" id="endDate" datetime-picker ng-required="false" hour="23" minute='59' class="calender-icon" />
+ <span ng-show="newschedulermodalForm.startDate.$error.endBeforeStart">To date must be on or after From date.</span>
+ <span ng-show="newschedulermodalForm.startDate.$error.invalidDate || newschedulermodalForm.endDate.$error.invalidDate">Check dates for validity</span>
+ <span ng-show="newschedulermodalForm.startDate.$error.required || newschedulermodalForm.endDate.$error.required">A required date is missing</span>
+ </div>
+
+ <div class="form-group" >
+ <label>Please Select Option For Duration and FallBack</label>
+
+ <select class="form-control" name="selecttime" data-tests-id="timeUnitSelect" ng-model="vm.selectedOption" ng-change="vm.updateMinMax()">
+ <option value="hours">HOURS</option>
+ <option value="minutes">MINUTES</option>
+ <option value="seconds">SECONDS</option>
+ </select>
+ </div>
+ <div class="row">
+ <div class="form-group col-md-6 col-xs-12">
+ <label class="control-label">Duration</label>
+ <input type="number" style="font-size: 1em;" data-tests-id="durationInput" name="durationinput" ng-model="vm.scheduler.duration" ng-required="true">
+
+ </div>
+ <div class="form-group col-md-6 col-xs-12" >
+ <label class="control-label">Fallback Duration</label>
+ <input type="number" style="font-size: 1em;" name="fallbackinput" data-tests-id="fallbackInput" ng-model="vm.scheduler.fallbackDuration" ng-required="true">
+
+
+ </div>
+ </div>
+ <div class="form-group">
+ <label class="control-label">Concurrency Limit</label>
+ <input type="number" style="font-size: 1em;" name="input" data-tests-id="concurrencyLimitInput" ng-model="vm.scheduler.concurrency" min="1" max="30" ng-required="true">
+ </div>
+ <div class="form-group">
+ <label class="control-label">Policy</label>
+ <select class="policy-combo" ng-model="vm.scheduler.policy" id="policy" ng-options="item.policyName for item in vm.policys">
+ <option value="">Select Policy</option>
+ </select>
+ </div>
+ <div class="form-group">
+ <button type="submit" id="find" name="Find" ng-disabled="vm.isClicked" class="btn btn-primary find-block">Find</button>
+ <span class="spinner" ng-show="vm.isSpinnerVisible">
+ <img src="app/vid/images/spinner.gif">
+ </img>
+
+ </span>
+
+ </div>
+
+ <div class="form-group" ng-show="(vm.checkboxSelection=='false')? true:false">
+<!-- <label class="control-label">Time Slots</label> -->
+<!-- <textarea rows="10" cols="50" class="timeslots-block" ></textarea> -->
+ <table class="table table-bordered">
+ <thead class="thead-default">
+ <tr>
+ <th>Start Time</th>
+ <th>End Time</th>
+ </tr>
+ </thead>
+ <tbody>
+
+ <tr class="table-headline-row" ng-repeat="timeslot in vm.timeSlots">
+ <td>{{timeslot.startTime}}</td>
+ <td>{{timeslot.finishTime}}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ </div>
+ <div class="modal-footer">
+ <div class="pull-right">
+ <button type="button" id="btn" name="submit" class="btn btn-primary" ng-click="vm.submit()">Schedule</button>
+ <button type="button" id="btn" name="submit" class="btn btn-primary" ng-click="vm.reject()">Reject</button>
+ <button type="button" id="cancel" name="cancel" class="btn btn-white" ng-click="vm.close()">Cancel</button>
+ </div>
+ </div>
+</form>
+
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.css b/vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.css
new file mode 100644
index 000000000..d545a5cdc
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.css
@@ -0,0 +1,7 @@
+.modal-header h3 {
+ border-bottom: 3px solid #00aeef;
+}
+
+.btn-primary {
+ padding: 4px 9px !important;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.html
new file mode 100644
index 000000000..911e86c24
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/modals/pending-change-management/pending-change-management.html
@@ -0,0 +1,12 @@
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/new-change-management/new-change-management.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/scripts/modals/pending-change-management/pending-change-management.css" />
+<div class="modal-header">
+ <h3 class="modal-title" id="pending-modal-header">Pending</h3>
+ <span id="cancel" ng-click="vm.close()" class="pull-right modal-close" aria-hidden="true">&times;</span>
+</div>
+<div class="modal-body">
+ <span id="pending-modal-content">{{vm.content}}</span>
+</div>
+<div class="modal-footer">
+ <div ng-include="'app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.html'"></div>
+</div>
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js
index 09c70eb5b..a10f602bf 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/aaiService.js
@@ -20,9 +20,9 @@
"use strict";
-var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONENT, FIELD) {
+var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONENT, FIELD, $q) {
return {
- getSubscriberName: function (globalCustomerId,
+ getSubscriberName : function(globalCustomerId,
successCallbackFunction) {
$log
.debug("AaiService:getSubscriberName: globalCustomerId: "
@@ -31,9 +31,9 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
COMPONENT.AAI_SUB_DETAILS_PATH
+ globalCustomerId + COMPONENT.ASSIGN + Math.random(),
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
var subName = "";
if (response.data) {
subName = response.data[FIELD.ID.SUBNAME];
@@ -44,7 +44,7 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
},
- runNamedQuery: function (namedQueryId, globalCustomerId, serviceType, serviceInstanceId, successCallback, errorCallback) {
+ runNamedQuery : function (namedQueryId, globalCustomerId, serviceType, serviceInstanceId, successCallback, errorCallback) {
var url = COMPONENT.AAI_SUB_VIEWEDIT_PATH +
COMPONENT.FORWARD_SLASH + encodeURIComponent(namedQueryId) +
@@ -52,30 +52,54 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
COMPONENT.FORWARD_SLASH + encodeURIComponent(serviceType) +
COMPONENT.FORWARD_SLASH + encodeURIComponent(serviceInstanceId);
$http.get(url, {}, {
- timeout: PropertyService.getServerResponseTimeoutMsec()
- }).then(function (response) {
+
+
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(function(response) {
if (response.data != null) {
successCallback(response);
} else {
errorCallback(response);
}
- }, function (response) {
+ }, function(response) {
errorCallback(response);
});
},
- getSubDetails: function (selectedSubscriber, selectedServiceInstance, successCallback, errorCallback) {
+ getVNFInformationByServiceTypeAndId : function (globalCustomerId, serviceType, serviceInstanceId, successCallback, errorCallback) {
+
+ var url = COMPONENT.AAI_GET_VNF_INFO +
+ COMPONENT.FORWARD_SLASH + encodeURIComponent(globalCustomerId) +
+ COMPONENT.FORWARD_SLASH + encodeURIComponent(serviceType) +
+ COMPONENT.FORWARD_SLASH + encodeURIComponent(serviceInstanceId);
+ $http.get(url, {}, {
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data != null) {
+ successCallback(response);
+ } else {
+ errorCallback(response);
+ }
+ }, function(response) {
+ errorCallback(response);
+ });
+ },
+
+
+ getSubDetails : function(selectedSubscriber, selectedServiceInstance, successCallback, errorCallback) {
var subscriber;
var displayData;
- $http.get(COMPONENT.AAI_SUB_DETAILS_PATH + selectedSubscriber, {}, {
- timeout: PropertyService.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ $http.get( COMPONENT.AAI_SUB_DETAILS_PATH + selectedSubscriber, {}, {
+
+
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(function(response) {
displayData = [];
subscriber = response.data;
var subscriberName = subscriber[FIELD.ID.SUBNAME];
if (subscriber[FIELD.ID.SERVICE_SUBSCRIPTIONS] != null) {
- angular.forEach(subscriber[FIELD.ID.SERVICE_SUBSCRIPTIONS][FIELD.ID.SERVICE_SUBSCRIPTION], function (serviceSubscription, key) {
+ angular.forEach(subscriber[FIELD.ID.SERVICE_SUBSCRIPTIONS][FIELD.ID.SERVICE_SUBSCRIPTION], function(serviceSubscription, key) {
var serviceInstanceId = [];
var serviceType = "";
if (serviceSubscription[FIELD.ID.SERVICETYPE] != null) {
@@ -84,10 +108,9 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
serviceType = FIELD.PROMPT.NO_SERVICE_SUB;
}
if (serviceSubscription[FIELD.ID.SERVICE_INSTANCES] != null) {
- angular.forEach(serviceSubscription[FIELD.ID.SERVICE_INSTANCES][FIELD.ID.SERVICE_INSTANCE], function (instValue, instKey) {
+ angular.forEach(serviceSubscription[FIELD.ID.SERVICE_INSTANCES][FIELD.ID.SERVICE_INSTANCE], function(instValue, instKey) {
// put them together, i guess
- var inst = {
- "serviceInstanceId": instValue[FIELD.ID.SERVICE_INSTANCE_ID],
+ var inst = { "serviceInstanceId": instValue[FIELD.ID.SERVICE_INSTANCE_ID],
"aaiModelInvariantId": instValue[FIELD.ID.MODEL_INVAR_ID],
"aaiModelVersionId": instValue[FIELD.ID.MODEL_VERSION_ID],
"serviceInstanceName": instValue[FIELD.ID.SERVICE_INSTANCE_NAME]
@@ -102,111 +125,109 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
});
} else {
if (serviceInstanceId == []) {
- serviceInstanceId = [FIELD.PROMPT.NO_SERVICE_INSTANCE];
+ serviceInstanceId = [ FIELD.PROMPT.NO_SERVICE_INSTANCE ];
}
}
- angular.forEach(serviceInstanceId, function (subVal, subKey) {
+ angular.forEach(serviceInstanceId, function(subVal, subKey) {
displayData.push({
- globalCustomerId: selectedSubscriber,
- subscriberName: subscriberName,
- serviceType: serviceType,
- serviceInstanceId: subVal.serviceInstanceId,
- aaiModelInvariantId: subVal.aaiModelInvariantId,
- aaiModelVersionId: subVal.aaiModelVersionId,
- serviceInstanceName: subVal.serviceInstanceName,
+ globalCustomerId : selectedSubscriber,
+ subscriberName : subscriberName,
+ serviceType : serviceType,
+ serviceInstanceId : subVal.serviceInstanceId,
+ aaiModelInvariantId : subVal.aaiModelInvariantId,
+ aaiModelVersionId
+ : subVal.aaiModelVersionId,
+ serviceInstanceName : subVal.serviceInstanceName,
isPermitted: serviceSubscription[FIELD.ID.IS_PERMITTED]
});
});
});
} else {
displayData.push({
- globalCustomerId: selectedSubscriber,
- subscriberName: selectedSubscriberName,
- serviceType: FIELD.PROMPT.NO_SERVICE_SUB,
- serviceInstanceId: FIELD.PROMPT.NO_SERVICE_INSTANCE
+ globalCustomerId : selectedSubscriber,
+ subscriberName : selectedSubscriberName,
+ serviceType : FIELD.PROMPT.NO_SERVICE_SUB,
+ serviceInstanceId : FIELD.PROMPT.NO_SERVICE_INSTANCE
});
}
successCallback(displayData, subscriberName);
- }, function (response) {
- errorCallback(response);
- });
+ }, function(response) {
+ errorCallback(response);});
},
- getSubList: function (successCallback, errorCallback) {
- $http.get(FIELD.ID.AAI_GET_FULL_SUBSCRIBERS, {}, {
- timeout: PropertyService.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ getSubList : function(successCallback, errorCallback ) {
+
+ $http.get( FIELD.ID.AAI_GET_FULL_SUBSCRIBERS, {}, {
+
+
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(function(response) {
var customerList = [];
if (response.data.customer != null) {
- angular.forEach(response.data.customer, function (subVal, subKey) {
- var cust = {
- "globalCustomerId": subVal[FIELD.ID.GLOBAL_CUSTOMER_ID],
- "subscriberName": subVal[FIELD.ID.SUBNAME],
- "isPermitted": subVal[FIELD.ID.IS_PERMITTED],
- };
+ angular.forEach(response.data.customer, function(subVal, subKey) {
+ var cust = { "globalCustomerId": subVal[FIELD.ID.GLOBAL_CUSTOMER_ID], "subscriberName": subVal[FIELD.ID.SUBNAME],
+ "isPermitted": subVal[FIELD.ID.IS_PERMITTED], };
customerList.push(cust);
});
successCallback(customerList);
} else {
errorCallback(response);
}
- }, function (response) {
+ },function(response) {
errorCallback(response);
});
},
- getServices2: function (successCallback, errorCallback) {
+ getServices2 : function(successCallback, errorCallback ) {
- $http.get(FIELD.ID.AAI_GET_SERVICES, {}, {
- timeout: PropertyService.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ $http.get( FIELD.ID.AAI_GET_SERVICES, {}, {
+
+
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(function(response) {
var customerList = [];
if (response.data != null) {
var serviceIdList = [];
- angular.forEach(response.data, function (value, key) {
- angular.forEach(value, function (subVal, key) {
- var newVal = {
- "id": subVal[FIELD.ID.SERVICE_ID],
- "description": subVal[FIELD.ID.SERVICE_DESCRIPTION],
+ angular.forEach(response.data, function(value, key) {
+ angular.forEach(value, function(subVal, key) {
+ var newVal = { "id" : subVal[FIELD.ID.SERVICE_ID], "description" : subVal[FIELD.ID.SERVICE_DESCRIPTION] ,
"isPermitted" : subVal[FIELD.ID.IS_PERMITTED]
- };
- serviceIdList.push(newVal);
+ };serviceIdList.push(newVal);
});
});
successCallback(serviceIdList);
} else {
errorCallback(response);
}
- }, function (response) {
+ },function(response) {
errorCallback(response);
});
},
- getSubscriptionServiceTypeList: function (globalCustomerId,
+ getSubscriptionServiceTypeList : function(globalCustomerId,
successCallbackFunction) {
$log
.debug("AaiService:getSubscriptionServiceTypeList: globalCustomerId: "
+ globalCustomerId);
- if (UtilityService.hasContents(globalCustomerId)) {
+ if ( UtilityService.hasContents(globalCustomerId) ) {
$http.get(
COMPONENT.AAI_SUB_DETAILS_PATH
+ globalCustomerId + COMPONENT.ASSIGN + Math.random(),
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data && response.data[FIELD.ID.SERVICE_SUBSCRIPTIONS]) {
var serviceTypes = [];
var serviceSubscriptions = response.data[FIELD.ID.SERVICE_SUBSCRIPTIONS][FIELD.ID.SERVICE_SUBSCRIPTION];
for (var i = 0; i < serviceSubscriptions.length; i++) {
serviceTypes.push({
- "name": serviceSubscriptions[i][FIELD.ID.SERVICETYPE],
+ "name":serviceSubscriptions[i][FIELD.ID.SERVICETYPE],
"isPermitted": serviceSubscriptions[i][FIELD.ID.IS_PERMITTED],
"id": i
- });
- }
+ });}
successCallbackFunction(serviceTypes);
} else {
successCallbackFunction([]);
@@ -215,19 +236,19 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
(UtilityService.runHttpErrorHandler);
}
},
- getLcpCloudRegionTenantList: function (globalCustomerId, serviceType,
+ getLcpCloudRegionTenantList : function(globalCustomerId, serviceType,
successCallbackFunction) {
$log
.debug("AaiService:getLcpCloudRegionTenantList: globalCustomerId: "
+ globalCustomerId);
- var url = COMPONENT.AAI_GET_TENANTS
+ var url = COMPONENT.AAI_GET_TENANTS
+ globalCustomerId + COMPONENT.FORWARD_SLASH + serviceType + COMPONENT.ASSIGN + Math.random();
$http.get(url,
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
var lcpCloudRegionTenants = [];
var aaiLcpCloudRegionTenants = response.data;
@@ -242,24 +263,23 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
"cloudRegionId": aaiLcpCloudRegionTenants[i][COMPONENT.CLOUD_REGION_ID],
"tenantName": aaiLcpCloudRegionTenants[i][COMPONENT.TENANT_NAME],
"tenantId": aaiLcpCloudRegionTenants[i][COMPONENT.TENANT_ID],
- "isPermitted": aaiLcpCloudRegionTenants[i][COMPONENT.IS_PERMITTED]
- });
+ "isPermitted": aaiLcpCloudRegionTenants[i][COMPONENT.IS_PERMITTED]});
}
successCallbackFunction(lcpCloudRegionTenants);
})["catch"]
(UtilityService.runHttpErrorHandler);
},
- getSubscribers: function (successCallbackFunction) {
+ getSubscribers : function(successCallbackFunction) {
$log
.debug("AaiService:getSubscribers");
- var url = FIELD.ID.AAI_GET_SUBSCRIBERS + COMPONENT.ASSIGN + Math.random();
+ var url = FIELD.ID.AAI_GET_SUBSCRIBERS + COMPONENT.ASSIGN + Math.random();
$http.get(url,
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data) {
successCallbackFunction(response.data.customer);
} else {
@@ -268,16 +288,16 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
})["catch"]
(UtilityService.runHttpErrorHandler);
},
- getProvOptionsFromSystemProp: function (successCallbackFunction) {
+ getProvOptionsFromSystemProp : function(successCallbackFunction) {
$log
.debug("AaiService:getProvOptionsFromSystemProp");
- var url = COMPONENT.GET_SYSTEM_PROP_VNF_PROV_STATUS_PATH;
+ var url = COMPONENT.GET_SYSTEM_PROP_VNF_PROV_STATUS_PATH;
$http.get(url,
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data) {
successCallbackFunction(response);
} else {
@@ -286,28 +306,31 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
})["catch"]
(UtilityService.runHttpErrorHandler);
},
- getLoggedInUserID: function (successCallbackFunction) {
+ getLoggedInUserID : function(successCallbackFunction) {
$log
.debug("AaiService:getLoggedInUserID");
var url = COMPONENT.GET_USER_ID;
$http.get(url,
{
- timeout: PropertyService
+ transformResponse: [function (data) {
+ return data;
+ }],
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data) {
successCallbackFunction(response);
} else {
successCallbackFunction([]);
}
- })["catch"]
+ },function(failure){console.log("failure")})["catch"]
(UtilityService.runHttpErrorHandler);
},
- getServices: function (successCallbackFunction) {
+ getServices : function(successCallbackFunction) {
$log
.debug("AaiService:getServices");
- var url = COMPONENT.AAI_GET_SERVICES + COMPONENT.ASSIGN + Math.random();
+ var url = COMPONENT.AAI_GET_SERVICES + COMPONENT.ASSIGN + Math.random();
$http.get(url,
{
@@ -326,31 +349,46 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
getAicZones: function (successCallbackFunction) {
$log
.debug("getAicZones:getAicZones");
- var url = COMPONENT.AAI_GET_AIC_ZONES + COMPONENT.ASSIGN + Math.random();
+ var url = COMPONENT.AAI_GET_AIC_ZONES +COMPONENT.ASSIGN + Math.random();
$http.get(url,
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data) {
successCallbackFunction(response);
} else {
successCallbackFunction([]);
}
})["catch"]
- (UtilityService.runHttpErrorHandler);
- },
- getServiceModels: function (globalCustomerId, serviceType, successCallbackFunction) {
+ (UtilityService.runHttpErrorHandler);},
+ getAicZoneForPNF: function (globalCustomerId,serviceType,serviceInstanceId,successCallbackFunction) {
+ $log
+ .debug("getAicZones:getAicZones");
+ var url = COMPONENT.AAI_GET_AIC_ZONE_FOR_PNF
+ .replace('@serviceInstanceId', serviceInstanceId)
+ .replace('@globalCustomerId', globalCustomerId)
+ .replace('@serviceType', serviceType);
+ $http.get(url,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ successCallbackFunction(response.data);
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);},
+
+ getServiceModels : function(globalCustomerId,serviceType,successCallbackFunction) {
$log
.debug("AaiService:getServices");
- var url = COMPONENT.AAI_GET_SERVICES + COMPONENT.FORWARD_SLASH + globalCustomerId + COMPONENT.FORWARD_SLASH + serviceType + COMPONENT.ASSIGN + Math.random();
+ var url = COMPONENT.AAI_GET_SERVICES + COMPONENT.FORWARD_SLASH+globalCustomerId+ COMPONENT.FORWARD_SLASH +serviceType+COMPONENT.ASSIGN + Math.random();
$http.get(url,
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data) {
successCallbackFunction(response);
} else {
@@ -359,16 +397,16 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
})["catch"]
(UtilityService.runHttpErrorHandler);
},
- getServiceModelsByServiceType: function (namedQueryId, globalCustomerId, serviceType, successCallbackFunction) {
+ getServiceModelsByServiceType : function(namedQueryId,globalCustomerId,serviceType,successCallbackFunction) {
$log
.debug("AaiService:getServiceModelsByServiceType");
- var url = COMPONENT.AAI_GET_SERVICES_BY_TYPE + COMPONENT.FORWARD_SLASH + namedQueryId + COMPONENT.FORWARD_SLASH + globalCustomerId + COMPONENT.FORWARD_SLASH + serviceType + COMPONENT.ASSIGN + Math.random();
+ var url = COMPONENT.AAI_GET_SERVICES_BY_TYPE+COMPONENT.FORWARD_SLASH+namedQueryId+COMPONENT.FORWARD_SLASH+globalCustomerId+COMPONENT.FORWARD_SLASH +serviceType+COMPONENT.ASSIGN + Math.random();
$http.get(url,
{
- timeout: PropertyService
+ timeout : PropertyService
.getServerResponseTimeoutMsec()
- }).then(function (response) {
+ }).then(function(response) {
if (response.data) {
successCallbackFunction(response);
} else {
@@ -376,9 +414,71 @@ var AaiService = function ($http, $log, PropertyService, UtilityService, COMPONE
}
})["catch"]
(UtilityService.runHttpErrorHandler);
+ },
+
+ getVnfsByCustomerIdAndServiceType: function(globalSubscriberId, serviceType){
+ var deferred = $q.defer();
+
+ if (UtilityService.hasContents(globalSubscriberId) &&
+ UtilityService.hasContents(serviceType) ) {
+
+ $http.get(COMPONENT.AAI_GET_VNF_BY_CUSTOMERID_AND_SERVICETYPE + globalSubscriberId + COMPONENT.FORWARD_SLASH
+ + serviceType )
+ .success(function (response) {
+ if(response) {
+ deferred.resolve({data: response});
+ } else {
+ deferred.resolve({data: []});
+ }
+ }).error(function (data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+ }
+
+ return deferred.promise;
+ },
+
+ getVnfVersionsByInvariantId: function(modelInvariantId){
+ var deferred = $q.defer();
+
+ if (UtilityService.hasContents(modelInvariantId)) {
+ var body = {"versions" : modelInvariantId}
+ $http.post(( COMPONENT.AAI_GET_VERSION_BY_INVARIANT_ID),body)
+
+ .success(function (response) {
+ if(response) {
+ deferred.resolve({data: response});
+ } else {
+ deferred.resolve({data: []});
+ }
+ }).error(function (data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+ }
+
+ return deferred.promise;
+ },
+
+ getSubscriberServiceTypes: function(subscriberUuid) {
+ var deferred = $q.defer();
+ $log.debug("AaiService:getSubscriberServiceTypes: subscriberUuid: " + subscriberUuid);
+
+ if (UtilityService.hasContents(subscriberUuid)) {
+ $http.get(COMPONENT.AAI_SUB_DETAILS_PATH + subscriberUuid + COMPONENT.ASSIGN + Math.random())
+ .success(function (response) {
+ if(response && [FIELD.ID.SERVICE_SUBSCRIPTIONS]) {
+ deferred.resolve({data: response[FIELD.ID.SERVICE_SUBSCRIPTIONS][FIELD.ID.SERVICE_SUBSCRIPTION]});
+ } else {
+ deferred.resolve({data: []});
+ }
+ }).error(function (data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+ }
+
+ return deferred.promise;
}
- }
-}
+ }};
appDS2.factory("AaiService", ["$http", "$log", "PropertyService",
- "UtilityService", "COMPONENT", "FIELD", AaiService]);
+ "UtilityService", "COMPONENT", "FIELD", "$q", AaiService]);
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/change-management.service.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/change-management.service.js
new file mode 100644
index 000000000..f2282d69a
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/change-management.service.js
@@ -0,0 +1,76 @@
+(function () {
+ 'use strict';
+
+ appDS2.service('changeManagementService', ['$http', '$q', 'COMPONENT', 'VIDCONFIGURATION', changeManagementService]);
+
+ function changeManagementService($http, $q, COMPONENT, VIDCONFIGURATION) {
+ this.getWorkflows = function (vnfs) {
+ var deferred = $q.defer();
+
+ $http.get(COMPONENT.GET_WORKFLOW.replace("@vnfs", vnfs))
+ .success(function (response) {
+ deferred.resolve({data: response});
+ }).error(function (data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+
+ return deferred.promise;
+ };
+
+ this.getMSOChangeManagements = function() {
+ var deferred = $q.defer();
+
+ $http.get(COMPONENT.GET_MSO_WORKFLOWS)
+ .success(function (response) {
+ deferred.resolve({data: response});
+ })
+ .error(function(data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+
+ return deferred.promise;
+ };
+
+ this.getAllSDCServices = function () {
+ var deferred = $q.defer();
+
+ $http.get(COMPONENT.SERVICES_DIST_STATUS_PATH + VIDCONFIGURATION.ASDC_MODEL_STATUS)
+ .success(function (response) {
+ deferred.resolve({data: response});
+ })
+ .error(function(data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+
+ return deferred.promise;
+ };
+
+ this.getSDCService = function(uuid) {
+ var deferred = $q.defer();
+
+ $http.get(COMPONENT.SERVICES_PATH + uuid)
+ .success(function (response) {
+ deferred.resolve({data: response});
+ })
+ .error(function(data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+
+ return deferred.promise;
+ };
+
+ this.getSchedulerChangeManagements = function(){
+ var deferred = $q.defer();
+
+ $http.get(COMPONENT.GET_SCHEDULER_CHANGE_MANAGEMENTS)
+ .success(function (response) {
+ deferred.resolve({data: response});
+ })
+ .error(function(data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+
+ return deferred.promise;
+ };
+ }
+})();
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/creationService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/creationService.js
index 9309ce6cc..e171e2856 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/services/creationService.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/creationService.js
@@ -274,7 +274,6 @@ var CreationService = function($log, AaiService, AsdcService, DataService,VIDCON
}
parameterList.push(FIELD.PARAMETER.SUPPRESS_ROLLBACK);
if(_this.componentId === COMPONENT.VF_MODULE ){
- if(DataService.getSubscriberName() === FIELD.NAME.MOBILITY){
parameterList.push({name: FIELD.NAME.SDN_C_PRELOAD,
id: FIELD.ID.SDN_C_PRELOAD,
type: "checkbox",
@@ -283,7 +282,6 @@ var CreationService = function($log, AaiService, AsdcService, DataService,VIDCON
hideFieldAndLabel: true
}
);
- }
parameterList.push({name: FIELD.NAME.UPLOAD_SUPPLEMENTORY_DATA_FILE,
id: FIELD.ID.UPLOAD_SUPPLEMENTORY_DATA_FILE,
type: "checkbox",
@@ -602,7 +600,7 @@ var CreationService = function($log, AaiService, AsdcService, DataService,VIDCON
requestDetails.requestParameters.usePreload = getValueFromList(
FIELD.ID.SDN_C_PRELOAD, parameterList);
if(_this.componentId == COMPONENT.VF_MODULE &&(requestDetails.requestParameters.usePreload== null || requestDetails.requestParameters.usePreload === '')){
- requestDetails.requestParameters.usePreload = true;
+ requestDetails.requestParameters.usePreload = false;
}
break;
case COMPONENT.VOLUME_GROUP:
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/msoService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/msoService.js
index 864abe67d..68c8503dc 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/services/msoService.js
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/msoService.js
@@ -20,156 +20,240 @@
"use strict";
-var MsoService = function($http, $log, PropertyService, UtilityService, COMPONENT, FIELD) {
+var MsoService = function($http, $log, PropertyService, AaiService, UtilityService, COMPONENT, FIELD, $q) {
- var _this = this;
+ var _this = this;
/*
* Common function to handle both create and delete instance requests
*/
- var requestInstanceUpdate = function(request, successCallbackFunction) {
- $log.debug("MsoService:requestInstanceUpdate: request:");
- $log.debug(request);
- $http.post( "mso/" + request.url, {
- requestDetails : request.requestDetails
- }, {
- timeout : PropertyService.getServerResponseTimeoutMsec()
- }).then(successCallbackFunction)["catch"]
- (UtilityService.runHttpErrorHandler);
- }
-
- var checkValidStatus = function(response) {
- if (response.data.status < 200 || response.data.status > 202) {
- throw {
- type : FIELD.ID.MSO_FAILURE
- }
- }
- }
-
- var addListEntry = function(name, value) {
- var entry = '"' + name + '": ';
- if (value === undefined) {
- return entry + "undefined";
- } else {
- return entry + '"' + value + '"';
- }
- }
-
- return {
- createInstance : requestInstanceUpdate,
- deleteInstance : requestInstanceUpdate,
- getOrchestrationRequest : function(requestId, successCallbackFunction) {
- $log.debug("MsoService:getOrchestrationRequest: requestId: "
- + requestId);
- $http.get(
- "mso/mso_get_orch_req/"
- + requestId + "?r=" + Math.random(),
- {
- timeout : PropertyService
- .getServerResponseTimeoutMsec()
- }).then(successCallbackFunction)["catch"]
- (UtilityService.runHttpErrorHandler);
- },
- getOrchestrationRequests : function(filterString,
- successCallbackFunction) {
- $log.debug("MsoService:getOrchestrationRequests: filterString: "
- + filterString);
- $http.get(
- "mso/mso_get_orch_reqs/"
- + encodeURIComponent(filterString) + "?r="
- + Math.random(),
- {
- timeout : PropertyService
- .getServerResponseTimeoutMsec()
- }).then(successCallbackFunction)["catch"]
- (UtilityService.runHttpErrorHandler);
- },
- getFormattedCommonResponse : function(response) {
- return UtilityService.getCurrentTime() + " HTTP Status: "
- + UtilityService.getHttpStatusText(response.data.status)
- + "\n" + angular.toJson(response.data.entity, true)
-
- },
- checkValidStatus : checkValidStatus,
- getFormattedGetOrchestrationRequestsResponse : function(response) {
- UtilityService.checkUndefined(COMPONENT.ENTITY, response.data.entity);
- UtilityService.checkUndefined(COMPONENT.STATUS, response.data.status);
- checkValidStatus(response);
-
- var list = response.data.entity.requestList
- UtilityService.checkUndefined(FIELD.ID.REQUEST_LIST, list);
-
- var message = "";
-
- for (var i = 0; i < list.length; i++) {
- var request = list[i].request;
- message += addListEntry(FIELD.ID.REQUEST_ID, request.requestId) + ",\n";
- message += addListEntry(FIELD.ID.REQUEST_TYPE, request.requestType)
- + ",\n";
- var status = request.requestStatus;
- if (status === undefined) {
- message += addListEntry(FIELD.ID.REQUEST_STATUS, undefined) + "\n";
- } else {
- message += addListEntry(FIELD.ID.TIMESTAMP, status.timestamp)
- + ",\n";
- message += addListEntry(FIELD.ID.REQUEST_STATE, status.requestState)
- + ",\n";
- message += addListEntry(FIELD.ID.REQUEST_STATUS,
- status.statusMessage)
- + ",\n";
- message += addListEntry(FIELD.ID.PERCENT_PROGRESS,
- status.percentProgress)
- + "\n";
- }
- if (i < (list.length - 1)) {
- message += "\n";
- }
- }
- return message;
- },
- getFormattedSingleGetOrchestrationRequestResponse : function (response) {
- UtilityService.checkUndefined(COMPONENT.ENTITY, response.data.entity);
- UtilityService.checkUndefined(COMPONENT.STATUS, response.data.status);
- checkValidStatus(response);
-
- var message = "";
- if ( UtilityService.hasContents (response.data.entity.request) ) {
- var request = response.data.entity.request;
- message += addListEntry(FIELD.ID.REQUEST_ID, request.requestId) + ",\n";
- message += addListEntry(FIELD.ID.REQUEST_TYPE, request.requestType)
- + ",\n";
- var status = request.requestStatus;
- if (status === undefined) {
- message += addListEntry(FIELD.ID.REQUEST_STATUS, undefined) + "\n";
- } else {
- message += addListEntry(FIELD.ID.TIMESTAMP, status.timestamp)
- + ",\n";
- message += addListEntry(FIELD.ID.REQUEST_STATE, status.requestState)
- + ",\n";
- message += addListEntry(FIELD.ID.REQUEST_STATUS,
- status.statusMessage)
- + ",\n";
- message += addListEntry(FIELD.ID.PERCENT_PROGRESS,
- status.percentProgress)
- + "\n\n";
- }
- }
- return message;
- },
- showResponseContentError : function(error, showFunction) {
- switch (error.type) {
- case "undefinedObject":
- showFunction(FIELD.ERROR.SYSTEM_FAILURE, error.message);
- break;
- case "msoFailure":
- showFunction(FIELD.ERROR.MSO, "")
- break;
- default:
- showFunction(FIELD.ERROR.SYSTEM_FAILURE);
- }
- }
- }
-}
+ var requestInstanceUpdate = function(request, successCallbackFunction) {
+ $log.debug("MsoService:requestInstanceUpdate: request:");
+ $log.debug(request);
+ $http.post( "mso/" + request.url, {
+ requestDetails : request.requestDetails
+ }, {
+ timeout : PropertyService.getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ }
+
+ var checkValidStatus = function(response) {
+ if (response.data.status < 200 || response.data.status > 202) {
+ throw {
+ type : FIELD.ID.MSO_FAILURE
+ }
+ }
+ };
+
+ var addListEntry = function(name, value) {
+ var entry = '"' + name + '": ';
+ if (value === undefined) {
+ return entry + "undefined";
+ } else {
+ return entry + '"' + value + '"';
+ }
+ };
+
+ var activateInstance = function(instance, model) {
+ var deferred = $q.defer();
+
+ AaiService.getLoggedInUserID(function (response) {
+ var userID = response.data;
+
+ AaiService.getAicZoneForPNF(instance.globalCustomerId, model.service.serviceType, instance.serviceInstanceId, function (aicZone) {
+
+ var requestDetails = {
+ "modelInstanceId": serviceInstanceId,
+ "requestDetails": {
+ "modelInfo": {
+ "modelType": "service",
+ "modelInvariantId": model.service.invariantUuid,
+ "modelVersionId": model.service.uuid,
+ "modelName": model.service.name,
+ "modelVersion": model.service.version
+ },
+ "requestInfo": {
+ "source": "VID",
+ "requestorId": userID
+ },
+ "requestParameters": {
+ "userParams": {
+ "name": "aic_zone",
+ "value": aicZone
+ }
+ }
+ }
+ };
+
+ console.log("requestDetails", requestDetails);
+
+ $http.post(COMPONENT.MSO_ACTIVATE_INSTANCE.replace('@serviceInstanceId', requestDetails.modelInstanceId),
+ requestDetails.requestDetails)
+ .success(function (response) {
+ deferred.resolve({data: response});
+ })
+ .error(function(data, status, headers, config) {
+ deferred.reject({message: data, status: status});
+ });
+ });
+ });
+
+ return deferred.promise;
+ };
+
+ return {
+ createInstance : requestInstanceUpdate,
+ deleteInstance : requestInstanceUpdate,
+ getOrchestrationRequest : function(requestId, successCallbackFunction) {
+ $log.debug("MsoService:getOrchestrationRequest: requestId: "
+ + requestId);
+ $http.get(
+ "mso/mso_get_orch_req/"
+ + requestId + "?r=" + Math.random(),
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getOrchestrationRequests : function(filterString,
+ successCallbackFunction) {
+ $log.debug("MsoService:getOrchestrationRequests: filterString: "
+ + filterString);
+ $http.get(
+ "mso/mso_get_orch_reqs/"
+ + encodeURIComponent(filterString) + "?r="
+ + Math.random(),
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(successCallbackFunction)["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getFormattedCommonResponse : function(response) {
+ return UtilityService.getCurrentTime() + " HTTP Status: "
+ + UtilityService.getHttpStatusText(response.data.status)
+ + "\n" + angular.toJson(response.data.entity, true)
+
+ },
+ checkValidStatus : checkValidStatus,
+ getFormattedGetOrchestrationRequestsResponse : function(response) {
+ UtilityService.checkUndefined(COMPONENT.ENTITY, response.data.entity);
+ UtilityService.checkUndefined(COMPONENT.STATUS, response.data.status);
+ checkValidStatus(response);
+
+ var list = response.data.entity.requestList
+ UtilityService.checkUndefined(FIELD.ID.REQUEST_LIST, list);
+
+ var message = "";
+
+ for (var i = 0; i < list.length; i++) {
+ var request = list[i].request;
+ message += addListEntry(FIELD.ID.REQUEST_ID, request.requestId) + ",\n";
+ message += addListEntry(FIELD.ID.REQUEST_TYPE, request.requestType)
+ + ",\n";
+ var status = request.requestStatus;
+ if (status === undefined) {
+ message += addListEntry(FIELD.ID.REQUEST_STATUS, undefined) + "\n";
+ } else {
+ message += addListEntry(FIELD.ID.TIMESTAMP, status.timestamp)
+ + ",\n";
+ message += addListEntry(FIELD.ID.REQUEST_STATE, status.requestState)
+ + ",\n";
+ message += addListEntry(FIELD.ID.REQUEST_STATUS,
+ status.statusMessage)
+ + ",\n";
+ message += addListEntry(FIELD.ID.PERCENT_PROGRESS,
+ status.percentProgress)
+ + "\n";
+ }
+ if (i < (list.length - 1)) {
+ message += "\n";
+ }
+ }
+ return message;
+ },
+ getFormattedSingleGetOrchestrationRequestResponse : function (response) {
+ UtilityService.checkUndefined(COMPONENT.ENTITY, response.data.entity);
+ UtilityService.checkUndefined(COMPONENT.STATUS, response.data.status);
+ checkValidStatus(response);
+
+ var message = "";
+ if ( UtilityService.hasContents (response.data.entity.request) ) {
+ var request = response.data.entity.request;
+ message += addListEntry(FIELD.ID.REQUEST_ID, request.requestId) + ",\n";
+ message += addListEntry(FIELD.ID.REQUEST_TYPE, request.requestType)
+ + ",\n";
+ var status = request.requestStatus;
+ if (status === undefined) {
+ message += addListEntry(FIELD.ID.REQUEST_STATUS, undefined) + "\n";
+ } else {
+ message += addListEntry(FIELD.ID.TIMESTAMP, status.timestamp)
+ + ",\n";
+ message += addListEntry(FIELD.ID.REQUEST_STATE, status.requestState)
+ + ",\n";
+ message += addListEntry(FIELD.ID.REQUEST_STATUS,
+ status.statusMessage)
+ + ",\n";
+ message += addListEntry(FIELD.ID.PERCENT_PROGRESS,
+ status.percentProgress)
+ + "\n\n";
+ }
+ }
+ return message;
+ },
+ getManualTasks : function(requestId) {
+ $log.debug("MsoService:getManualTasks: requestId: "
+ + requestId);
+ return $http.get(
+ "mso/mso_get_man_task/" + requestId,
+ {
+ timeout: PropertyService
+ .getServerResponseTimeoutMsec()
+ })
+ .catch(UtilityService.runHttpErrorHandler);
+ },
+ completeTask: function(taskId, taskToComplete) {
+ $log.debug("MsoService:completeTask: taskId: "
+ + taskId);
+ AaiService.getLoggedInUserID(function (response) {
+ var attuid = response.data;
+ var source = "VID";
+ var data = {
+ requestDetails: {
+ requestInfo: {
+ source: source,
+ responseValue: taskToComplete,
+ requestorId: attuid
+ }
+ }
+ };
+
+ return $http.post(
+ "mso/mso_post_man_task/" + taskId, data,
+ {
+ timeout: PropertyService
+ .getServerResponseTimeoutMsec()
+ })
+ .catch(UtilityService.runHttpErrorHandler);
+ });
+ },
+ showResponseContentError : function(error, showFunction) {
+ switch (error.type) {
+ case "undefinedObject":
+ showFunction(FIELD.ERROR.SYSTEM_FAILURE, error.message);
+ break;
+ case "msoFailure":
+ showFunction(FIELD.ERROR.MSO, "")
+ break;
+ default:
+ showFunction(FIELD.ERROR.SYSTEM_FAILURE);
+ }
+ },
+ activateInstance: activateInstance
+ }
+};
appDS2.factory("MsoService", [ "$http", "$log", "PropertyService",
- "UtilityService", "COMPONENT", "FIELD", MsoService ]);
+ "AaiService", "UtilityService", "COMPONENT", "FIELD", "$q", MsoService ]);
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/services/schedulerService.js b/vid-app-common/src/main/webapp/app/vid/scripts/services/schedulerService.js
new file mode 100644
index 000000000..83cc4ddac
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/services/schedulerService.js
@@ -0,0 +1,104 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * VID
+ * ================================================================================
+ * Copyright (C) 2017 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=========================================================
+ */
+
+"use strict";
+
+var SchedulerService = function($http, $log, PropertyService, UtilityService, COMPONENT, FIELD) {
+ return {
+
+ getStatusSchedulerId : function(schedulerInfo,successCallbackFunction) {
+ $log
+ .debug("SchedulerService:getSchedulerStatusAndSchedulerId");
+ var url = COMPONENT.POST_CREATE_NEW_VNF_CHANGE+COMPONENT.ASSIGN + Math.random();
+
+ $http.post(url, schedulerInfo,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data) {
+ successCallbackFunction(response);
+ } else {
+ successCallbackFunction([]);
+ }
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+
+ getTimeSotsForSchedulerId:function(schedulerID,successCallbackFunction){
+ $log
+ .debug("SchedulerService:getTimeSlotsForSchedulerID");
+ var url = COMPONENT.GET_TIME_SLOTS+COMPONENT.FORWARD_SLASH +schedulerID+COMPONENT.ASSIGN;
+
+ $http.get(url,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data) {
+ successCallbackFunction(response);
+ } else {
+ successCallbackFunction([]);
+ }
+ })["catch"]
+
+ (UtilityService.runHttpErrorHandler);
+ },
+ getSubmitForapprovedTimeslots: function(ApprovedTimeSlotsObj,successCallbackFunction) {
+ $log
+ .debug("SchedulerService:getSchedulerStatusAndSchedulerId");
+ var url = COMPONENT.SUBMIT_VNF_CHANGE_TIMESLOTS+COMPONENT.ASSIGN + Math.random();
+
+ $http.post(url, ApprovedTimeSlotsObj,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data) {
+ successCallbackFunction(response);
+ } else {
+ successCallbackFunction([]);
+ }
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);
+ },
+ getPolicyInfo:function(policyName,successCallbackFunction){
+ $log
+ .debug("SchedulerService:getPolicyInfo");
+ var url = COMPONENT.GET_POLICY +COMPONENT.ASSIGN + Math.random();
+
+ $http.post(url, policyName,
+ {
+ timeout : PropertyService
+ .getServerResponseTimeoutMsec()
+ }).then(function(response) {
+ if (response.data) {
+ successCallbackFunction(response);
+ } else {
+ successCallbackFunction([]);
+ }
+ })["catch"]
+ (UtilityService.runHttpErrorHandler);
+ }
+ }
+}
+
+appDS2.factory("SchedulerService", ["$http", "$log", "PropertyService",
+ "UtilityService", "COMPONENT", "FIELD", SchedulerService]);
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/view-models/change-management.html b/vid-app-common/src/main/webapp/app/vid/scripts/view-models/change-management.html
new file mode 100644
index 000000000..0f42ec874
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/view-models/change-management.html
@@ -0,0 +1,112 @@
+<link rel="stylesheet" type="text/css" href="app/vid/styles/change-management.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/styles/change-management-icons.css" />
+<div class="changes-management">
+ <div class="header">
+ <span id="change-management-headline">VNF Changes</span>
+ <span class="separator"></span>
+ <div class="button-container" ng-click="vm.createNewChange()">
+ <div class="icon-svg" id="change-management-new-button">
+ <svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 55.47337 55.63023"><path class="icon-filling" d="M27.7367.07843A27.73669,27.73669,0,1,0,55.4734,27.81512,27.73757,27.73757,0,0,0,27.7367.07843ZM40.18824,29.6178H29.53938V40.26666a1.80267,1.80267,0,0,1-3.60535,0V29.6178H15.28516a1.80267,1.80267,0,0,1,0-3.60535H25.934V15.36359a1.80267,1.80267,0,0,1,3.60535,0V26.01245H40.18824a1.80267,1.80267,0,1,1,0,3.60535Z"/></svg>
+ </div>
+ <span class="button-text">New</span>
+ </div>
+
+ <input type="search" id="change-management-search" class="search-changes" ng-change="vm.searchChanges()" ng-model-options="{debounce: 300}" ng-model="vm.searchChangesTerm" placeholder="Type to search">
+ </div>
+ <div class="jobs-table">
+ <div class="row">
+ <div class="col-md-12">
+ <uib-tabset active="activeJustified" justified="true">
+ <uib-tab index="0" heading="Active" id="active-tab">
+ <table class="table table-bordered" id="active-table">
+ <thead class="thead-default">
+ <tr>
+ <th class="col-md-5">VNF Name</th>
+ <th class="col-md-2">Type</th>
+ <th class="col-md-2">Flow</th>
+ <th class="col-md-2">Start time</th>
+ <th>Status</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class="table-headline-row">
+ <th>
+ <span id="in-progress-table-head">IN PROGRESS</span>
+ </th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ </tr>
+ <tr ng-repeat="changeManagement in vm.changeManagements | changeManagementsByStatuses:{statuses: ['FAILED', 'INPROGRESS', 'PENDING']}">
+ <th scope="row">{{changeManagement.instanceReferences.vnfInstanceName || 'No-Instance-Name'}}</th>
+ <td>{{changeManagement.requestScope}}</td>
+ <td>{{changeManagement.requestType}}</td>
+ <td>{{changeManagement.startTime}}</td>
+ <td class="centered" ng-if="changeManagement.requestStatus.requestState == 'FAILED'"><span class="icon-x" ng-click="vm.openFailedModal({details: changeManagement.requestStatus.statusMessage, job: changeManagement})"></span></td>
+ <td class="centered" ng-if="changeManagement.requestStatus.requestState == 'INPROGRESS'"><span class="icon-process" ng-click="vm.openInProgressModal({details: changeManagement.requestStatus.statusMessage, job: changeManagement})"></span></td>
+ <td class="centered" ng-if="changeManagement.requestStatus.requestState == 'PENDING'"><span class="icon-alert" ng-click="vm.openAlertModal({details: changeManagement.requestStatus.statusMessage, job: changeManagement})"></span></td>
+ <td class="centered"><span class="icon-view"></span></td>
+ </tr>
+ <tr class="table-headline-row">
+ <th>
+ <span id="pending-table-head">PENDING</span>
+ </th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ </tr>
+ <tr ng-repeat="changeManagement in vm.pendingChangeManagements">
+ <th scope="row">{{changeManagement.vnfName}}</th>
+ <td>{{changeManagement.scheduleRequest.scheduleName}}</td>
+ <td>{{changeManagement.workflow}}</td>
+ <td>{{changeManagement.startTime}}</td>
+ <td class="centered"><span class="icon-pending" ng-click="vm.openPendingModal({details: 'change management is pending in scheduler and waiting to be deployed'})"></span></td>
+ <td class="centered"><span class="icon-view"></span></td>
+ </tr>
+ </tbody>
+ </table>
+ </uib-tab>
+ <uib-tab index="1" heading="Finished" id="finished-tab">
+ <table class="table table-bordered" id="finished-table">
+ <thead class="thead-default">
+ <tr>
+ <th class="col-md-5">VNF Name</th>
+ <th class="col-md-2">Type</th>
+ <th class="col-md-2">Flow</th>
+ <th class="col-md-2">Start time</th>
+ <th>Status</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr class="table-headline-row">
+ <th>
+ <span id="finished-table-head">FINISHED</span>
+ </th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ <th></th>
+ </tr>
+ <tr ng-repeat="changeManagement in vm.changeManagements | changeManagementsByStatuses:{statuses: ['COMPLETE']}">
+ <th scope="row">{{changeManagement.instanceReferences.vnfInstanceName || 'No-Instance-Name'}}</th>
+ <td>{{changeManagement.requestScope}}</td>
+ <td>{{changeManagement.requestType}}</td>
+ <td>{{changeManagement.startTime}}</td>
+ <td></td>
+ <td class="centered"><span class="icon-view"></span></td>
+ </tr>
+ </tbody>
+ </table>
+ </uib-tab>
+ </uib-tabset>
+ </div>
+ </div>
+ </div>
+</div> \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/scripts/view-models/instantiate.htm b/vid-app-common/src/main/webapp/app/vid/scripts/view-models/instantiate.htm
index 27622ff6e..71efef1dd 100755
--- a/vid-app-common/src/main/webapp/app/vid/scripts/view-models/instantiate.htm
+++ b/vid-app-common/src/main/webapp/app/vid/scripts/view-models/instantiate.htm
@@ -105,6 +105,9 @@
<a class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="describeService(aService.instance)" style="margin-right: 8px;">
<span class="glyphicon glyphicon-info-sign"></span>
</a>
+ <a data-tests-id="activateButton" class="pull-right btn btn-primary btn-xs" data-nodrag ng-click="activateMSOInstance()" style="margin-right: 8px;">
+ Activate
+ </a>
</div>
<ol ui-tree-nodes="" ng-model="aService.instance.vnfs" ng-class="{hidden: collapsed}">
<li ng-repeat="vnf in aService.instance.vnfs" ui-tree-node>
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/angularjs-datetime-picker.css b/vid-app-common/src/main/webapp/app/vid/styles/angularjs-datetime-picker.css
new file mode 100644
index 000000000..16bad31e4
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/angularjs-datetime-picker.css
@@ -0,0 +1,76 @@
+.angularjs-datetime-picker {
+ color: #333;
+ font: normal 14px sans-serif;
+ border: 1px solid #ddd;
+ display: inline-block;
+ background: #fff;
+ z-index: 99999;
+}
+.angularjs-datetime-picker > .adp-month {
+ text-align: center;
+ line-height: 22px;
+ padding: 10px;
+ background: #00aeef;
+ text-transform: uppercase;
+ font-weight: bold;
+ border-bottom: 1px solid #ddd;
+ position: relative;
+}
+.angularjs-datetime-picker > .adp-month > button {
+ color: #555;
+ font: normal 14px sans-serif;
+ outline: none;
+ position: absolute;
+ background: transparent;
+ border: none;
+ cursor: pointer;
+}
+.angularjs-datetime-picker > .adp-month > button:hover {
+ color: #333;
+}
+.angularjs-datetime-picker > .adp-month > button.adp-prev {
+ left: 10px;
+}
+.angularjs-datetime-picker > .adp-month > button.adp-next {
+ right: 10px;
+}
+.angularjs-datetime-picker > .adp-days {
+ width: 210px; /* 30 x 7 */
+ margin: 10px;
+ text-align: center;
+}
+.angularjs-datetime-picker > .adp-days > .adp-day-of-week, .angularjs-datetime-picker > .adp-days > .adp-day {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ border: 1px solid transparent;
+ width: 30px;
+ line-height: 28px;
+ float: left;
+ border-radius: 25px;
+}
+.angularjs-datetime-picker > .adp-days > .adp-day-of-week {
+ font-weight: bold;
+}
+.angularjs-datetime-picker > .adp-days > .adp-day:not(.selectable) {
+ opacity: 0.15;
+ cursor: default;
+}
+.angularjs-datetime-picker > .adp-days > .adp-day.selectable {
+ cursor: pointer;
+}
+.angularjs-datetime-picker > .adp-days > .adp-day.selected {
+ background: #e0e0e0;
+}
+.angularjs-datetime-picker > .adp-days > .adp-day.selectable:hover {
+ background: #00aeef;
+}
+.angularjs-datetime-picker > .adp-days:after {
+ content: '';
+ display: block;
+ clear: left;
+ height: 0;
+}
+
+.angularjs-datetime-picker input[type=range] {
+ width: 150px;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/change-management-icons.css b/vid-app-common/src/main/webapp/app/vid/styles/change-management-icons.css
new file mode 100644
index 000000000..8c4dbd8c5
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/change-management-icons.css
@@ -0,0 +1,82 @@
+@font-face {
+ font-family: 'icomoon';
+ src: url('fonts/icomoon.eot?4cilop');
+ src: url('fonts/icomoon.eot?4cilop#iefix') format('embedded-opentype'),
+ url('fonts/icomoon.ttf?4cilop') format('truetype'),
+ url('fonts/icomoon.woff?4cilop') format('woff'),
+ url('fonts/icomoon.svg?4cilop#icomoon') format('svg');
+ font-weight: normal;
+ font-style: normal;
+}
+
+.changes-management [class^="icon-"],.changes-management [class*=" icon-"] {
+ /* use !important to prevent issues with browser extensions that change fonts */
+ font-family: 'icomoon' !important;
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-finished_d:before {
+ content: "\e90c";
+ color: #4ca90c;
+}
+.icon-noun_573805_cc-03:before {
+ content: "\e90a";
+}
+.icon-scedular:before {
+ content: "\e90b";
+}
+.icon-alert:before {
+ content: "\e901";
+ color: #ffb81c;
+ cursor: pointer;
+}
+.icon-close_hover:before {
+ content: "\e902";
+}
+.icon-close:before {
+ content: "\e903";
+ color: #5a5a5a;
+}
+.icon-dearch_hover:before {
+ content: "\e904";
+ color: #5a5a5a;
+}
+.icon-pending:before {
+ content: "\e905";
+ color: #00aeef;
+ cursor: pointer;
+}
+.icon-plus:before {
+ content: "\e906";
+}
+.icon-process:before {
+ content: "\e900";
+ color: #4ca90c;
+ font-size: 17px;
+ cursor: pointer;
+}
+.icon-search:before {
+ content: "\e907";
+ color: #5a5a5a;
+}
+.icon-view:before {
+ content: "\e908";
+ color: #959595;
+ font-size: 16px;
+ cursor: pointer;
+}
+.icon-x:before {
+ content: "\e909";
+ color: #cf2a2a;
+ font-size: 12px;
+ cursor: pointer;
+}
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/change-management.css b/vid-app-common/src/main/webapp/app/vid/styles/change-management.css
new file mode 100644
index 000000000..68a06ee16
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/change-management.css
@@ -0,0 +1,157 @@
+.body-content-jsp {
+ margin-top: 35px;
+ min-height: 500px;
+ margin-left: 201px;
+ margin-right: 0px;
+ background-color: #f8f8f8;
+}
+
+.changes-management {
+ background: white;
+ color: #797979;
+}
+
+.changes-management .header {
+ height: 76px;
+ padding: 13px 0px 0px 26px;
+ background: #00aeef;
+}
+
+.changes-management #change-management-headline {
+ font-family: "Open Sans";
+ color: #ffffff;
+ font-size: 24px;
+ font-weight: 400;
+ line-height: 24px;
+ text-align: left;
+}
+
+
+.changes-management .separator {
+ width: 1px;
+ font-size: 35px;
+ background: #00aeef;
+ border-left: 1px solid #d2d2d2;
+ margin: 0px 30px 0px 30px;
+}
+
+.changes-management .header .button-container {
+ display: initial;
+}
+
+.changes-management .header .icon-svg {
+ display: inline;
+ color: #ffffff;
+ position: relative;
+ top: 9px;
+}
+
+.changes-management .header .button-text {
+ position: relative;
+ font-family: "Open Sans";
+ color: #ffffff;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 24px;
+ text-align: left;
+ bottom: 5px;
+ left: 5px;
+}
+
+.changes-management .header .icon-filling {
+ width: 40px;
+ height: 40px;
+ fill: #ffffff;
+}
+
+.changes-management .header .search-changes {
+ width: 361px;
+ float: right;
+ height: 41px;
+ border: 0px;
+ background-color: #59c2ed;
+ color: #ffffff;
+ margin-right: 15px;
+ border-radius: 10px;
+ top: 6px;
+}
+
+.changes-management .header .search-changes::placeholder {
+ font-family: "Open Sans";
+ color: #ffffff;
+ text-align: left;
+ font-size: 14px;
+ line-height: 40px;
+ font-style: italic;
+}
+
+.att-accordion__toggle {
+ font-size: 14px;
+}
+
+.jobs-table {
+ background-color: #f8f8f8;
+ padding: 40px;
+}
+
+.nav-tabs.nav-justified {
+ width: 30%;
+ margin-right:2px;
+ border:0px;
+ border-radius:0px;
+}
+
+.uib-tab.nav-item {
+ border: 1px solid #d2d2d2;
+ background-color: #f8f8f8;
+}
+
+.uib-tab.nav-item.active {
+ border-top: 4px solid #00aeef;
+}
+
+.nav-tabs.nav-justified>li>a {
+ border-radius:0px!important;
+ border: 0px!important;
+}
+
+.table {
+ border: 1px solid #eaeaea;
+ box-sizing: border-box;
+ background-color: #ffffff;
+ box-shadow: 0px 2px 7px 0px rgba(34, 31, 31, 0.17);
+ font-family: "Open Sans";
+ color: #5a5a5a;
+ font-size: 14px;
+ font-weight: 400;
+}
+
+.table>thead {
+ background-color: #d2d2d2;
+ font-family: "Open Sans";
+ color: #191919;
+ font-size: 13px;
+ font-weight: 600;
+ line-height: 40px;
+}
+
+.table-headline-row {
+ font-family: "Open Sans";
+ color: #00aeef;
+ font-size: 14px;
+ font-weight: 600;
+ background-color: #eaeaea;
+ box-shadow: 0px 1px 1px 0px rgba(34, 31, 31, 0.19);
+}
+
+.table-bordered{border:1px solid #eaeaea;}
+.table-bordered>tbody>tr>td,
+.table-bordered>tbody>tr>th,
+.table-bordered>tfoot>tr>td,
+.table-bordered>tfoot>tr>th,
+.table-bordered>thead>tr>td,
+.table-bordered>thead>tr>th{border:1px solid #eaeaea;}
+
+.centered {
+ text-align: center;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/common.css b/vid-app-common/src/main/webapp/app/vid/styles/common.css
new file mode 100644
index 000000000..8d6fb615b
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/common.css
@@ -0,0 +1,3 @@
+html, body {
+ font-size:14px;
+} \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.eot b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.eot
new file mode 100644
index 000000000..e57ccc5e7
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.eot
Binary files differ
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.svg b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.svg
new file mode 100644
index 000000000..5d514c47b
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Generated by IcoMoon</metadata>
+<defs>
+<font id="icomoon" horiz-adv-x="1024">
+<font-face units-per-em="1024" ascent="960" descent="-64" />
+<missing-glyph horiz-adv-x="1024" />
+<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
+<glyph unicode="&#xe900;" glyph-name="process" d="M631.646 246.003c0 3.88 0.539 7.761 0.539 11.749-0.004 0.383-0.007 0.834-0.007 1.287 0 4.063 0.198 8.081 0.585 12.042l-0.040-0.502c-0.361 2.651-0.567 5.715-0.567 8.827 0 0.687 0.010 1.371 0.030 2.052l-0.002-0.1c0 3.719-0.539 7.437-0.539 11.21 26.43 12.179 48.879 24.977 70.103 39.439l-1.657-1.066c3.777 2.631 6.217 6.952 6.217 11.844 0 1.016-0.105 2.007-0.305 2.963l0.016-0.094c-4.423 18.505-9.784 34.428-16.377 49.694l0.747-1.944c-2.25 5.102-7.144 8.659-12.9 8.945l-0.035 0.001c-7.871 0.492-17.069 0.773-26.333 0.773-19.785 0-39.272-1.28-58.382-3.761l2.255 0.239-0.539 0.593c-3.647 7.094-7.767 13.212-12.509 18.784l0.114-0.137c-5.071 6.721-10.014 12.621-15.232 18.264l0.142-0.155c11.157 19.513 21.869 42.472 30.726 66.333l1.072 3.299c0.401 1.296 0.632 2.785 0.632 4.328 0 4.429-1.901 8.414-4.932 11.183l-0.012 0.011c-12.333 10.122-26.056 19.898-40.426 28.722l-1.611 0.92c-2.319 1.362-5.108 2.166-8.084 2.166s-5.765-0.804-8.161-2.207l0.076 0.041c-24.388-14.877-45.538-30.781-65.017-48.489l0.343 0.307c-5.389 2.21-10.779 4.096-16.168 5.928l-7.006 2.425c-7.006 1.94-14.552 4.15-22.636 5.928-4.417 28.524-10.424 53.569-18.231 77.805l0.985-3.538c-2.026 5.462-6.963 9.387-12.877 9.912l-0.058 0.004c-8.48 0.724-18.35 1.137-28.317 1.137-8.431 0-16.793-0.296-25.077-0.877l1.116 0.063c-5.677-0.152-10.473-3.765-12.365-8.799l-0.031-0.094c-9.201-21.373-17.193-46.613-22.702-72.769l-0.473-2.683c-8.084-1.832-16.168-4.096-24.253-6.36l-5.928-2.102c-5.389-1.832-10.779-3.611-16.168-5.713-17.796 18.222-37.178 34.73-57.977 49.359l-1.307 0.871c-2.466 1.762-5.543 2.817-8.866 2.817-2.676 0-5.192-0.684-7.382-1.887l0.080 0.040c-15.204-8.735-28.235-17.643-40.524-27.442l0.642 0.494-2.695-1.832c-3.35-2.48-5.497-6.419-5.497-10.859 0-1.474 0.237-2.892 0.674-4.219l-0.027 0.095c7.457-28.224 17.034-52.771 28.99-75.888l-0.965 2.052c-5.156-5.301-9.935-11.037-14.251-17.123l-0.301-0.446c-4.954-5.7-9.42-12.074-13.186-18.889l-0.287-0.567-0.539-0.323c-23.512 4.276-50.861 6.981-78.748 7.485l-0.477 0.007c-0.25 0.016-0.543 0.025-0.837 0.025-6.027 0-11.165-3.805-13.144-9.144l-0.031-0.097-1.617-3.18c-5.197-12.090-10.177-26.795-14.071-41.935l-0.481-2.205c-0.308-1.054-0.485-2.265-0.485-3.518 0-4.296 2.086-8.105 5.3-10.47l0.036-0.025c19.808-15.936 42.055-30.522 65.664-42.857l2.243-1.067c0-3.988-0.539-7.923-0.539-11.857 0.005-0.397 0.008-0.866 0.008-1.336 0-3.971-0.199-7.895-0.586-11.764l0.040 0.488c0.357-2.618 0.561-5.643 0.561-8.716 0-0.612-0.008-1.222-0.024-1.829l0.002 0.090c0-3.827 0.539-7.653 0.539-11.48-26.444-12.213-48.892-25.010-70.129-39.453l1.683 1.080c-3.823-2.421-6.324-6.629-6.324-11.42 0-1.15 0.144-2.267 0.415-3.333l-0.020 0.093c4.411-18.495 9.772-34.419 16.373-49.681l-0.743 1.931c2.225-5.133 7.129-8.716 12.9-8.999l0.034-0.001c7.772-0.47 16.858-0.738 26.006-0.738 19.899 0 39.502 1.267 58.733 3.724l-2.28-0.238 0.539-0.701c3.933-7.079 8.036-13.16 12.599-18.856l-0.203 0.263c4.851-6.306 9.701-12.342 15.091-18.109-11.191-19.521-21.904-42.464-30.74-66.317l-1.058-3.261c-0.491-1.375-0.775-2.962-0.775-4.615 0-4.352 1.969-8.245 5.065-10.835l0.022-0.018c12.332-10.128 26.053-19.938 40.412-28.814l1.626-0.936c2.24-1.322 4.936-2.102 7.815-2.102s5.574 0.781 7.888 2.142l-0.073-0.040c24.597 14.961 45.92 30.882 65.607 48.585l-0.395-0.349c5.389-2.264 10.779-4.15 16.168-5.982l7.006-2.425c7.006-2.048 15.091-4.204 22.636-5.875 4.417-28.503 10.424-53.528 18.231-77.746l-0.984 3.533c1.873-5.589 6.885-9.621 12.89-10.022l0.044-0.002c10.24-0.647 19.941-1.132 30.181-1.132 7.006 0 14.552 0 22.097 0.862 5.549 0.483 10.189 3.936 12.358 8.745l0.038 0.094c9.191 21.366 17.183 46.606 22.699 72.759l0.476 2.694c8.084 1.779 16.168 3.988 24.253 6.413l5.928 2.048c4.851 1.779 10.24 3.557 15.629 5.767 18.022-18.073 37.566-34.607 58.431-49.401l1.392-0.937c2.466-1.762 5.543-2.817 8.866-2.817 2.676 0 5.192 0.684 7.382 1.887l-0.080-0.040c16.351 9.641 30.251 19.126 43.497 29.414l-0.92-0.688c3.282 2.649 5.364 6.672 5.364 11.181 0 1.353-0.187 2.662-0.538 3.903l0.024-0.101c-7.807 28.375-17.365 52.881-29.089 76.106l1.064-2.324c5.136 5.32 9.913 11.072 14.242 17.165l0.309 0.458c4.968 5.727 9.436 12.138 13.189 18.995l0.285 0.569h0.539c23.5-4.233 50.851-6.917 78.733-7.43l0.492-0.007c6.924 0.705 12.639 5.231 15.048 11.411l0.042 0.123c5.706 12.624 10.879 27.623 14.705 43.152l0.386 1.85c0.305 1.047 0.481 2.25 0.481 3.495 0 4.286-2.085 8.085-5.295 10.439l-0.036 0.025c-19.817 16.016-42.062 30.671-65.676 43.072l-2.231 1.068zM366.484 138.213c-69.948 3.144-125.467 60.616-125.467 131.055 0 72.449 58.731 131.18 131.18 131.18 72.443 0 131.17-58.722 131.18-131.162v-0.001c-1.734-72.771-61.136-131.1-134.162-131.1-0.96 0-1.918 0.010-2.873 0.030l0.143-0.002zM922.678 713.485c26.134 10.384 48.7 23.068 69.262 38.304l-0.816-0.577c3.748 2.471 6.187 6.661 6.187 11.422 0 0.936-0.094 1.85-0.274 2.733l0.015-0.088c-4.663 21.645-11.538 40.766-20.571 58.609l0.63-1.373c-2.233 4.494-6.643 7.609-11.812 7.974l-0.045 0.003c-7.813 0.794-16.885 1.247-26.062 1.247-19.779 0-39.066-2.103-57.652-6.097l1.794 0.323c-6.133 6.77-12.466 13-19.139 18.852l-0.263 0.226c-6.511 5.463-13.725 10.687-21.3 15.385l-0.797 0.46c1.663 11.334 2.612 24.419 2.612 37.726s-0.949 26.392-2.784 39.191l0.172-1.464c-0.696 5.472-4.523 9.896-9.604 11.454l-0.097 0.026c-17.778 6.201-38.458 10.704-59.878 12.644l-1.023 0.075c-0.601 0.086-1.296 0.135-2.001 0.135-4.907 0-9.262-2.368-11.983-6.023l-0.028-0.040c-15.292-20.204-27.898-43.558-36.649-68.716l-0.538-1.778c-10.263-1.606-19.342-3.896-28.080-6.916l1.133 0.34c-9.968-3.235-18.347-6.721-26.389-10.778l1.058 0.484c-19.74 14.879-42.31 27.691-66.463 37.4l-1.983 0.704c-1.679 0.707-3.63 1.117-5.677 1.117-3.579 0-6.865-1.255-9.441-3.348l0.028 0.022c-15.955-12.96-29.804-27.579-41.579-43.8l-0.459-0.663c-1.812-2.287-2.907-5.214-2.907-8.397 0-2.098 0.476-4.085 1.325-5.859l-0.035 0.082c12.025-25.438 27.185-47.251 45.35-66.157l-0.078 0.082c-2.749-6.899-5.519-15.564-7.756-24.44l-0.328-1.537c-1.329-7.45-2.294-16.318-2.68-25.336l-0.015-0.426c-26.34-10.247-49.099-22.945-69.778-38.288l0.793 0.562c-3.45-2.614-5.656-6.714-5.656-11.329 0-0.968 0.097-1.914 0.282-2.828l-0.015 0.091c4.17-21.542 10.891-40.71 19.975-58.469l-0.572 1.233c2.344-4.398 6.693-7.459 11.794-7.971l0.063-0.005c7.863-0.794 16.994-1.246 26.231-1.246 19.908 0 39.325 2.102 58.041 6.097l-1.813-0.324c5.992-6.919 12.336-13.161 19.143-18.868l0.259-0.211c6.516-5.635 13.74-10.851 21.402-15.409l0.695-0.383c-1.801-11.379-2.83-24.5-2.83-37.861s1.029-26.482 3.011-39.288l-0.182 1.427c0.72-5.305 4.274-9.632 9.064-11.447l0.098-0.033c17.913-6.146 38.775-10.646 60.363-12.639l1.077-0.080h0.539c0.318-0.025 0.689-0.039 1.064-0.039 4.856 0 9.163 2.353 11.843 5.981l0.028 0.040c15.266 20.21 27.869 43.56 36.644 68.706l0.543 1.788c10.548 1.698 19.807 4.004 28.752 6.996l-1.266-0.367c9.772 3.227 17.969 6.673 25.841 10.669l-1.049-0.483c19.759-14.675 42.311-27.455 66.375-37.3l2.072-0.75c1.748-0.728 3.779-1.151 5.909-1.151 3.684 0 7.072 1.266 9.754 3.386l-0.033-0.025c15.663 13.239 29.474 27.819 41.547 43.786l0.491 0.677c1.813 2.275 2.909 5.191 2.909 8.362 0 2.092-0.477 4.072-1.327 5.839l0.035-0.081c-12.455 25.328-27.568 47.105-45.424 66.295l0.153-0.166c2.695 8.515 5.389 17.192 7.545 26.031 1.477 7.336 2.628 16.169 3.203 25.158l0.031 0.604zM748.598 645.686c-39.582 1.979-70.925 34.554-70.925 74.449 0 41.165 33.371 74.536 74.536 74.536s74.536-33.371 74.536-74.536c0-0.007 0-0.014 0-0.021v0.001c-0.798-41.294-34.461-74.463-75.87-74.463-0.801 0-1.598 0.012-2.393 0.037l0.116-0.003z" />
+<glyph unicode="&#xe901;" glyph-name="alert" d="M1009.543 85.624l-445.139 775.529c-7.751 22.531-28.764 38.432-53.49 38.432-24.994 0-46.194-16.247-53.615-38.756l-0.114-0.399-444.536-774.445c-29.515-51.742-7.831-91.678 48.791-91.678h898.711c2.92-0.554 6.279-0.87 9.712-0.87 30.173 0 54.633 24.46 54.633 54.633 0 14.558-5.694 27.786-14.976 37.578l0.023-0.025zM510.795 689.483c28.815-6.731 49.95-32.201 49.95-62.607 0-4.296-0.422-8.493-1.226-12.553l0.067 0.408-9.035-247.868c5.094-7.524 8.132-16.801 8.132-26.788 0-26.614-21.575-48.188-48.188-48.188s-48.188 21.575-48.188 48.188c0 9.987 3.038 19.264 8.24 26.958l-0.109-0.17-9.035 247.868c-0.78 3.739-1.226 8.035-1.226 12.435 0 30.542 21.506 56.062 50.2 62.241l0.419 0.076zM510.795 105.201c-1.987-0.21-4.292-0.329-6.626-0.329-36.926 0-66.861 29.935-66.861 66.861s29.935 66.861 66.861 66.861c36.917 0 66.845-29.919 66.861-66.832v-0.002c0.18-1.752 0.283-3.785 0.283-5.843 0-33.427-27.093-60.526-60.517-60.536h-0.001z" />
+<glyph unicode="&#xe902;" glyph-name="close_hover" d="M1001.813 940.715c-12.348 12.319-29.391 19.936-48.213 19.936s-35.865-7.617-48.215-19.938l0.001 0.001-395.093-398.592-395.093 398.592c-12.153 12.396-29.072 20.080-47.787 20.080s-35.634-7.684-47.776-20.069l-0.011-0.011c-12.258-12.503-19.823-29.645-19.823-48.555s7.565-36.052 19.834-48.566l-0.011 0.011 391.68-395.349-391.68-395.093c-12.273-12.48-19.85-29.611-19.85-48.512s7.577-36.032 19.859-48.522l-0.009 0.010c12.291-12.443 29.352-20.15 48.213-20.15s35.923 7.707 48.207 20.144l0.007 0.007 394.24 398.165 395.093-398.165c12.291-12.443 29.352-20.15 48.213-20.15s35.923 7.707 48.207 20.144l0.007 0.007c12.273 12.48 19.85 29.611 19.85 48.512s-7.577 36.032-19.859 48.522l0.009-0.010-391.68 394.837 391.68 395.435c12.308 12.512 19.907 29.688 19.907 48.64s-7.599 36.128-19.916 48.649l0.009-0.009z" />
+<glyph unicode="&#xe903;" glyph-name="close" d="M1001.813 940.715c-12.348 12.319-29.391 19.936-48.213 19.936s-35.865-7.617-48.215-19.938l0.001 0.001-395.093-398.592-395.093 398.592c-12.153 12.396-29.072 20.080-47.787 20.080s-35.634-7.684-47.776-20.069l-0.011-0.011c-12.258-12.503-19.823-29.645-19.823-48.555s7.565-36.052 19.834-48.566l-0.011 0.011 391.68-395.349-391.68-395.093c-12.273-12.48-19.85-29.611-19.85-48.512s7.577-36.032 19.859-48.522l-0.009 0.010c12.291-12.443 29.352-20.15 48.213-20.15s35.923 7.707 48.207 20.144l0.007 0.007 394.24 398.165 395.093-398.165c12.291-12.443 29.352-20.15 48.213-20.15s35.923 7.707 48.207 20.144l0.007 0.007c12.273 12.48 19.85 29.611 19.85 48.512s-7.577 36.032-19.859 48.522l0.009-0.010-391.68 394.837 391.68 395.435c12.308 12.512 19.907 29.688 19.907 48.64s-7.599 36.128-19.916 48.649l0.009-0.009z" />
+<glyph unicode="&#xe904;" glyph-name="dearch_hover" d="M684.505 316.377h47.262l292.234-292.549-87.434-87.828-293.022 292.549v46.789l-17.329 17.566c-64.582-58.114-150.479-93.658-244.678-93.658-0.38 0-0.761 0.001-1.141 0.002h0.059c-210.042 0.045-380.298 170.328-380.298 380.377 0 210.076 170.3 380.377 380.377 380.377s380.377-170.3 380.377-380.377v0c0-0.188 0.001-0.411 0.001-0.634 0-94.356-35.571-180.403-94.035-245.465l0.299 0.338zM380.455 843.028c-0.070 0-0.153 0-0.236 0-145.431 0-263.326-117.895-263.326-263.326s117.895-263.326 263.326-263.326c145.431 0 263.326 117.895 263.326 263.326v0c0.002 0.422 0.004 0.921 0.004 1.421 0 144.648-117.26 261.908-261.908 261.908-0.417 0-0.833-0.001-1.25-0.003h0.064z" />
+<glyph unicode="&#xe905;" glyph-name="pending" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512c282.77 0 512 229.23 512 512v0c0 282.77-229.23 512-512 512v0zM219.429 521.143c40.396 0 73.143-32.747 73.143-73.143s-32.747-73.143-73.143-73.143c-40.396 0-73.143 32.747-73.143 73.143v0c0 40.396 32.747 73.143 73.143 73.143v0zM512 521.143c40.396 0 73.143-32.747 73.143-73.143s-32.747-73.143-73.143-73.143c-40.396 0-73.143 32.747-73.143 73.143v0c0 40.396 32.747 73.143 73.143 73.143v0zM804.571 521.143c40.396 0 73.143-32.747 73.143-73.143s-32.747-73.143-73.143-73.143c-40.396 0-73.143 32.747-73.143 73.143v0c0 40.396 32.747 73.143 73.143 73.143v0z" />
+<glyph unicode="&#xe906;" glyph-name="plus" d="M512 960v0c-282.77 0-512-229.23-512-512v0c0-282.77 229.23-512 512-512s512 229.23 512 512c0 282.77-229.23 512-512 512zM524.488 685.268c13.794 0 24.976-11.182 24.976-24.976v0-399.61c0-13.794-11.182-24.976-24.976-24.976s-24.976 11.182-24.976 24.976v0 399.61c0 13.794 11.182 24.976 24.976 24.976v0zM324.683 485.463h399.61c13.794 0 24.976-11.182 24.976-24.976s-11.182-24.976-24.976-24.976v0h-399.61c-13.794 0-24.976 11.182-24.976 24.976s11.182 24.976 24.976 24.976v0z" />
+<glyph unicode="&#xe907;" glyph-name="search" d="M684.505 316.377h47.262l292.234-292.549-87.434-87.828-293.022 292.549v46.789l-17.329 17.566c-64.582-58.114-150.479-93.658-244.678-93.658-0.38 0-0.761 0.001-1.141 0.002h0.059c-210.042 0.045-380.298 170.328-380.298 380.377 0 210.076 170.3 380.377 380.377 380.377s380.377-170.3 380.377-380.377v0c0-0.188 0.001-0.411 0.001-0.634 0-94.356-35.571-180.403-94.035-245.465l0.299 0.338zM380.455 843.028c-0.070 0-0.153 0-0.236 0-145.431 0-263.326-117.895-263.326-263.326s117.895-263.326 263.326-263.326c145.431 0 263.326 117.895 263.326 263.326v0c0.002 0.422 0.004 0.921 0.004 1.421 0 144.648-117.26 261.908-261.908 261.908-0.417 0-0.833-0.001-1.25-0.003h0.064z" />
+<glyph unicode="&#xe908;" glyph-name="view" d="M620.089 448c-1.432-58.584-49.263-105.529-108.059-105.529-59.696 0-108.089 48.393-108.089 108.089 0 59.685 48.376 108.072 108.057 108.089h0.002c59.856-0.735 108.096-49.429 108.096-109.39 0-0.443-0.003-0.885-0.008-1.327l0.001 0.067zM512 238.364c-1.627-0.045-3.541-0.071-5.461-0.071-115.81 0-209.692 93.883-209.692 209.692s93.883 209.692 209.692 209.692c115.805 0 209.684-93.874 209.692-209.677v-0.001c0.010-0.767 0.016-1.672 0.016-2.579 0-113.37-91.106-205.462-204.097-207.055l-0.15-0.002zM512 760.775c-282.738 0-512-311.296-512-311.296s229.262-314.311 512-314.311 512 314.311 512 314.311-229.262 311.296-512 311.296z" />
+<glyph unicode="&#xe909;" glyph-name="x" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512c282.77 0 512 229.23 512 512v0c0 282.77-229.23 512-512 512v0zM735.086 280.21c7.12-7.11 11.525-16.938 11.525-27.794s-4.405-20.684-11.524-27.794v0c-6.949-7.091-16.626-11.486-27.329-11.486-0.164 0-0.327 0.001-0.491 0.003h0.025c-10.823 0.154-20.601 4.504-27.804 11.493l0.010-0.010-167.497 167.79-167.497-167.643c-7.188-7-16.963-11.374-27.759-11.556h-0.035c-0.108-0.001-0.236-0.002-0.365-0.002-10.748 0-20.463 4.424-27.422 11.551l-0.007 0.008c-7.12 7.11-11.525 16.938-11.525 27.794s4.405 20.684 11.524 27.794v0l167.497 167.643-167.497 167.717c-7.113 7.113-11.513 16.94-11.513 27.794 0 21.709 17.598 39.307 39.307 39.307 10.854 0 20.681-4.4 27.794-11.513v0l167.497-167.717 167.497 167.79c7.113 7.113 16.94 11.513 27.794 11.513 21.709 0 39.307-17.598 39.307-39.307 0-10.854-4.4-20.681-11.513-27.794v0l-167.497-167.79z" />
+<glyph unicode="&#xe90a;" glyph-name="noun_573805_cc-03" d="M512.211 960c-282.886 0-512.211-229.325-512.211-512.211s229.325-512.211 512.211-512.211c282.887 0 512.211 229.325 512.211 512.211v0c-0.017 282.88-229.332 512.195-512.21 512.211h-0.001zM261.202 377.71c-38.703 0-70.079 31.375-70.079 70.079s31.375 70.079 70.079 70.079c38.703 0 70.079-31.375 70.079-70.079v0c0.005-0.298 0.007-0.649 0.007-1.001 0-38.155-30.93-69.085-69.085-69.085-0.352 0-0.703 0.003-1.054 0.008l0.053-0.001zM512.211 377.71c-38.703 0-70.079 31.375-70.079 70.079s31.375 70.079 70.079 70.079c38.703 0 70.079-31.375 70.079-70.079v0c0-0.061 0-0.133 0-0.205 0-38.59-31.284-69.874-69.874-69.874-0.072 0-0.144 0-0.216 0h0.011zM763.221 377.71c-38.703 0-70.079 31.375-70.079 70.079s31.375 70.079 70.079 70.079c38.703 0 70.079-31.375 70.079-70.079v0c0-0.061 0-0.133 0-0.205 0-38.59-31.284-69.874-69.874-69.874-0.072 0-0.144 0-0.217 0h0.011z" />
+<glyph unicode="&#xe90b;" glyph-name="scedular" horiz-adv-x="981" d="M981.333 662.699c0.312 4.17 0.49 9.033 0.49 13.938 0 109.691-88.922 198.613-198.613 198.613-5.353 0-10.656-0.212-15.902-0.627l0.693 0.044h-554.667c-4.553 0.371-9.857 0.583-15.21 0.583-109.691 0-198.613-88.922-198.613-198.613 0-4.905 0.178-9.768 0.527-14.583l-0.038 0.645v-470.699c0-128.811 82.475-256 213.333-256h554.667c130.859 0 213.333 127.189 213.333 256v470.699zM36.352 662.699c0 109.141 66.048 169.301 176.981 169.301h554.667c110.933 0 176.981-60.16 176.981-169.301l-6.315-44.032h-896zM938.667 192c0-109.141-59.733-213.333-170.667-213.333h-554.667c-110.933 0-170.667 104.192-170.667 213.333v384h896v-384zM362.667 405.333h256c11.782 0 21.333-9.551 21.333-21.333s-9.551-21.333-21.333-21.333v0h-256c-11.782 0-21.333 9.551-21.333 21.333s9.551 21.333 21.333 21.333v0zM362.667 234.667h256c11.782 0 21.333-9.551 21.333-21.333s-9.551-21.333-21.333-21.333v0h-256c-11.782 0-21.333 9.551-21.333 21.333s9.551 21.333 21.333 21.333v0zM704 960c11.782 0 21.333-9.551 21.333-21.333v0-170.667c0-11.782-9.551-21.333-21.333-21.333s-21.333 9.551-21.333 21.333v0 170.667c0 11.782 9.551 21.333 21.333 21.333v0zM277.333 960c11.782 0 21.333-9.551 21.333-21.333v0-170.667c0-11.782-9.551-21.333-21.333-21.333s-21.333 9.551-21.333 21.333v0 170.667c0 11.782 9.551 21.333 21.333 21.333v0z" />
+<glyph unicode="&#xe90c;" glyph-name="finished_d" d="M512 960v0c-282.77 0-512-229.23-512-512v0c0-282.77 229.23-512 512-512s512 229.23 512 512c0 282.77-229.23 512-512 512zM473.454 273.993c8.558 13.239 15.067 22.894 21.138 32.768 91.648 149.211 118.126 170.569 209.701 319.781 5.105 9.183 10.457 17.077 16.416 24.459l-0.252-0.322c8.798 10.219 21.751 16.651 36.206 16.651 9.048 0 17.507-2.52 24.715-6.896l-0.212 0.119c13.74-7.345 22.93-21.594 22.93-37.989 0-6.179-1.305-12.053-3.655-17.361l0.108 0.274c-3.479-7.646-7.067-14.1-11.098-20.236l0.346 0.561c-108.251-176.859-151.479-225.646-259.803-402.286-7.527-16.71-24.034-28.132-43.21-28.132-13.809 0-26.235 5.924-34.874 15.369l-0.032 0.036q-107.52 91.502-213.138 184.978c-11.444 7.654-18.878 20.525-18.878 35.132 0 11.575 4.668 22.060 12.224 29.675l-0.003-0.003c9.080 9.371 21.781 15.187 35.84 15.187s26.76-5.816 35.827-15.174l0.013-0.013c46.738-39.643 92.672-80.457 138.971-120.32z" />
+</font></defs></svg> \ No newline at end of file
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.ttf b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.ttf
new file mode 100644
index 000000000..7d0e36d1f
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.ttf
Binary files differ
diff --git a/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.woff b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.woff
new file mode 100644
index 000000000..b2d2e64af
--- /dev/null
+++ b/vid-app-common/src/main/webapp/app/vid/styles/fonts/icomoon.woff
Binary files differ
diff --git a/vid-app-common/src/test/java/org/opencomp/vid/controller/MsoControllerTest.java b/vid-app-common/src/test/java/org/opencomp/vid/controller/MsoControllerTest.java
new file mode 100644
index 000000000..9333ac9b0
--- /dev/null
+++ b/vid-app-common/src/test/java/org/opencomp/vid/controller/MsoControllerTest.java
@@ -0,0 +1,112 @@
+package org.opencomp.vid.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.apache.commons.lang.StringEscapeUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.openecomp.portalsdk.core.util.SystemProperties;
+import org.openecomp.vid.controller.MsoConfig;
+import org.openecomp.vid.controller.MsoController;
+import org.openecomp.vid.domain.mso.RequestInfo;
+import org.openecomp.vid.factories.MsoRequestFactory;
+import org.openecomp.vid.mso.rest.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(classes = {SystemProperties.class , MsoConfig.class})
+public class MsoControllerTest {
+
+ @Autowired
+ MsoRequestFactory msoRequestFactory;
+
+ @Test
+ public void testInstanceCreationNew() throws Exception {
+
+ RequestDetails requestDetails = msoRequestFactory.createMsoRequest("msoRequest.json");
+ MsoController msoController = new MsoController();
+ ResponseEntity<String> responseEntityNew = msoController.createSvcInstanceNew(null, requestDetails);
+ ResponseEntity<String> responseEntity = msoController.createSvcInstance(null, requestDetails);
+ assertEquals(responseEntityNew, responseEntity);
+
+ }
+
+ @Test
+ public void testInstanceCreationLocalWithRest() throws Exception {
+
+ RequestDetails requestDetails = msoRequestFactory.createMsoRequest("msoRequest.json");
+ MsoController msoController = new MsoController();
+ ResponseEntity<String> responseEntityNew = msoController.createSvcInstance(null, requestDetails);
+ ResponseEntity<String> responseEntityRest = msoController.createSvcInstanceNewRest(null, requestDetails);
+
+ assertEquals(responseEntityNew.getBody(), responseEntityRest.getBody());
+
+ }
+
+ @Test
+ public void testInstanceCreation() throws Exception {
+
+ RequestDetails requestDetails = msoRequestFactory.createMsoRequest("msoRequest.json");
+ MsoController msoController = new MsoController();
+ ResponseEntity<String> responseEntity = msoController.createSvcInstance(null, requestDetails);
+
+
+ assertEquals(responseEntity.getBody(), "{ \"status\": 200, \"entity\": {\n" +
+ " \"requestReferences\": {\n" +
+ " \"instanceId\": \"ba00de9b-3c3e-4b0a-a1ad-0c5489e711fb\",\n" +
+ " \"requestId\": \"311cc766-b673-4a50-b9c5-471f68914586\"\n" +
+ " }\n" +
+ "}}");
+
+ }
+
+ @Test
+ public void testGetOrchestrationRequestsForDashboard() throws Exception{
+ MsoController msoController = new MsoController();
+ List<Request> orchestrationRequestsForDashboard = msoController.getOrchestrationRequestsForDashboard();
+
+ assertEquals(orchestrationRequestsForDashboard.size() , 2);
+ }
+
+ @Test
+ public void testGetManualTasksByRequestId() throws Exception{
+ MsoController msoController = new MsoController();
+ List<Task> orchestrationRequestsForDashboard = msoController.getManualTasksByRequestId("za1234d1-5a33-55df-13ab-12abad84e335");
+
+ assertEquals(orchestrationRequestsForDashboard.get(0).getTaskId() , "daf4dd84-b77a-42da-a051-3239b7a9392c");
+ }
+
+
+ public void testCompleteManualTask() throws Exception{ // TODO not done yet
+ RequestInfo requestInfo = new RequestInfo();
+ requestInfo.setResponseValue("rollback");
+ requestInfo.setRequestorId("abc");
+ requestInfo.setSource("VID");
+ RequestDetails requestDetails = new RequestDetails();
+ requestDetails.setRequestInfo(requestInfo);
+ MsoController msoController = new MsoController();
+ ResponseEntity<String> responseEntity = msoController.manualTaskComplete("daf4dd84-b77a-42da-a051-3239b7a9392c" , requestDetails);
+ String assertString = "{ \\\"status\\\": 200, \\\"entity\\\": {\\n\" +\n" +
+ " \" \\\"taskRequestReference\\\": {\\n\" +\n" +
+ " \" \\\"taskId\\\": \\\"daf4dd84-b77a-42da-a051-3239b7a9392c\\\"\\n\" +\n" +
+ " \" }\\n\" +\n" +
+ " \"}\\n\" +\n" +
+ " \"}";
+ assertEquals(responseEntity.getBody() , StringEscapeUtils.unescapeJava(assertString));
+ }
+
+
+
+
+
+}
diff --git a/vid-app-common/src/test/java/org/opencomp/vid/controller/VidControllerTest.java b/vid-app-common/src/test/java/org/opencomp/vid/controller/VidControllerTest.java
index abf44bf77..f89d9cba0 100644
--- a/vid-app-common/src/test/java/org/opencomp/vid/controller/VidControllerTest.java
+++ b/vid-app-common/src/test/java/org/opencomp/vid/controller/VidControllerTest.java
@@ -11,6 +11,8 @@ import org.openecomp.sdc.tosca.parser.api.ISdcCsarHelper;
import org.openecomp.sdc.tosca.parser.exceptions.SdcToscaParserException;
import org.openecomp.sdc.tosca.parser.impl.SdcToscaParserFactory;
import org.openecomp.sdc.tosca.parser.impl.SdcTypes;
+import org.openecomp.vid.aai.AaiClient;
+import org.openecomp.vid.aai.AaiResponse;
import org.openecomp.vid.asdc.AsdcCatalogException;
import org.openecomp.vid.asdc.AsdcClient;
import org.openecomp.vid.asdc.parser.ToscaParserImpl2;
@@ -41,6 +43,7 @@ public class VidControllerTest {
@Autowired
private AsdcClient asdcClient;
+
@Autowired
ServletContext context;
public class Constants{
@@ -55,6 +58,19 @@ public class VidControllerTest {
private ToscaParserImpl2 p2 = new ToscaParserImpl2();
private ObjectMapper om = new ObjectMapper();
+
+ @Test
+ public void test() {
+ AaiClient client = new AaiClient(context);
+ AaiResponse<?> response = client.getVNFData();
+ try {
+ System.out.println(new ObjectMapper().writeValueAsString(response));
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
@Test
public void checkPNFFieldsExist() throws SdcToscaParserException {
String serviceRoleString = "serviceRole";
diff --git a/vid-app-common/src/test/java/org/openecomp/vid/services/ChangeManagementServiceTest.java b/vid-app-common/src/test/java/org/openecomp/vid/services/ChangeManagementServiceTest.java
new file mode 100644
index 000000000..f770ab2ab
--- /dev/null
+++ b/vid-app-common/src/test/java/org/openecomp/vid/services/ChangeManagementServiceTest.java
@@ -0,0 +1,29 @@
+package org.openecomp.vid.services;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.vid.changeManagement.ChangeManagementRequest;
+import org.openecomp.vid.changeManagement.ChangeManagementResponse;
+import org.springframework.http.ResponseEntity;
+
+import junit.framework.Assert;
+
+import static org.junit.Assert.*;
+
+
+public class ChangeManagementServiceTest {
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void doChangeManagement_requestTypeIsUpdateVnfNotFound_doUpdateAndReturnNull() throws Exception {
+
+ }
+
+} \ No newline at end of file
diff --git a/vid-app-common/src/test/resources/WEB-INF/conf/system.properties b/vid-app-common/src/test/resources/WEB-INF/conf/system.properties
index 4fbbe7cf7..6ec60859d 100644
--- a/vid-app-common/src/test/resources/WEB-INF/conf/system.properties
+++ b/vid-app-common/src/test/resources/WEB-INF/conf/system.properties
@@ -79,7 +79,7 @@ element_map_icon_path = app/fusionapp/icons/
#aai.oldserver.url=https://mtanjv9aaas40.aic.cip.att.com:8443/aai/servers/v3/
#ist servers
aai.server.url.base=https://aai-ext1.test.att.com:8443/aai/
-aai.server.url=https://aai-ext1.test.att.com:8443/aai/v10/
+aai.server.url=https://aai-ext1.test.att.com:8443/aai/v11/
aai.oldserver.url.base=https://aai-ext1.test.att.com:8443/aai/servers/
aai.oldserver.url=https://aai-ext1.test.att.com:8443/aai/servers/v3/
aai.truststore.filename=tomcat_keystore
@@ -88,6 +88,7 @@ aai.keystore.filename=aai-client-cert.p12
aai.keystore.passwd.x=OBF:1i9a1u2a1unz1lr61wn51wn11lss1unz1u301i6o
aai.use.client.cert=true
aai.vnf.provstatus=PREPROV,NVTPROV,PROV,CAPPED
+aai_get_version_by_invariant_id="service-design-and-creation/models?depth=2&model-invariant-id="
#Cron Schedules have 6 required fields and 1 optional field:
# Seconds Minutes Hours Day-of-Month Month Day-of-Week Year
@@ -139,17 +140,24 @@ mso.polling.interval.msecs=10000
mso.max.polls=10
mso.user.name=infraportal
mso.password.x=OBF:1ghz1kfx1j1w1m7w1i271e8q1eas1hzj1m4i1iyy1kch1gdz
-mso.restapi.svc.instance=/serviceInstances/v4
-mso.restapi.vnf.instance=/serviceInstances/v4/<service_instance_id>/vnfs
-mso.restapi.network.instance=/serviceInstances/v4/<service_instance_id>/networks
-mso.restapi.vf.module.instance=/serviceInstances/v4/<service_instance_id>/vnfs/<vnf_instance_id>/vfModules
-mso.restapi.volume.group.instance=/serviceInstances/v4/<service_instance_id>/vnfs/<vnf_instance_id>/volumeGroups
-mso.restapi.get.orc.req=/orchestrationRequests/v4
-mso.restapi.get.orc.reqs=/orchestrationRequests/v4?
+mso.restapi.svc.instance=/serviceInstances/v5
+mso.restapi.vnf.instance=/serviceInstances/v5/<service_instance_id>/vnfs
+mso.restapi.network.instance=/serviceInstances/v5/<service_instance_id>/networks
+mso.restapi.vf.module.instance=/serviceInstances/v5/<service_instance_id>/vnfs/<vnf_instance_id>/vfModules
+mso.restapi.volume.group.instance=/serviceInstances/v5/<service_instance_id>/vnfs/<vnf_instance_id>/volumeGroups
+mso.restapi.get.orc.req=/orchestrationRequests/v5
+mso.restapi.get.orc.reqs=/orchestrationRequests/v5?
+mso.restapi.get.man.tasks=/tasks/v1
vid.truststore.filename=/opt/app/vid/etc/vid_keystore.jks
mso.dme2.client.timeout=30000
mso.dme2.client.read.timeout=120000
+scheduler.server.url=http://mtanjv9sdlg10.aic.cip.att.com:8989/scheduler
+scheduler.create.new.vnf.change.instance=/v1/ChangeManagement/schedules/
+scheduler.get.time.slots=/v1/ChangeManagement/schedules/
+scheduler.get.schedules=/v1/ChangeManagement/schedules/scheduleDetails/
+
+
#vid.truststore.filename=/Users/Oren/Downloads/vid_keystore2.jks
vid.truststore.passwd.x=OBF:1wgg1wfq1uus1uui1x131x0r1x1v1x1j1uvo1uve1wg81wfi
diff --git a/vid-app-common/src/test/resources/WEB-INF/jsp/serviceModels.jsp b/vid-app-common/src/test/resources/WEB-INF/jsp/serviceModels.jsp
index 3280bc65a..9fdf75d64 100644
--- a/vid-app-common/src/test/resources/WEB-INF/jsp/serviceModels.jsp
+++ b/vid-app-common/src/test/resources/WEB-INF/jsp/serviceModels.jsp
@@ -6,6 +6,7 @@
<link rel="stylesheet" type="text/css" href="app/vid/styles/instantiate.css" />
<link rel="stylesheet" type="text/css" href="app/vid/styles/vidTree.css" />
<link rel="stylesheet" type="text/css" href="app/vid/styles/dialogs.css" />
+<link rel="stylesheet" type="text/css" href="app/vid/external/bootstrap/css/bootstrap.min.css" />
<script>
@@ -18,13 +19,19 @@
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
+<script src="app/vid/external/multiselect/angular-bootstrap-multiselect.min.js"></script>
<script src="app/vid/scripts/angular-ui-tree.js"></script>
+<script src="app/vid/external/lodash/lodash.min.js"></script>
<script src="app/vid/scripts/constants/componentConstants.js"></script>
<script src="app/vid/scripts/constants/fieldConstants.js"></script>
<script src="app/vid/scripts/constants/vidConfiguration.js"></script>
<script src="app/vid/scripts/constants/parameterConstants.js"></script>
+<script src="app/vid/scripts/filters/change-managements-by-statuses.filter.js"></script>
+<script src="app/vid/scripts/filters/date.filter.js"></script>
+<script src="app/vid/scripts/modals/change-management-manual-tasks-controller/change-management-manual-tasks.controller.js"></script>
+<script src="app/vid/scripts/modals/new-change-management/new-change-management.controller.js"></script>
<script src="app/vid/scripts/controller/aaiSubscriberController.js"></script>
<script src="app/vid/scripts/controller/creationDialogController.js"></script>
<script src="app/vid/scripts/controller/deletionDialogController.js"></script>
@@ -35,6 +42,8 @@
<script src="app/vid/scripts/controller/ServiceModelController.js"></script>
<script src="app/vid/scripts/controller/previousVersionDialogController.js"></script>
<script src="app/vid/scripts/controller/previousVersionContoller.js"></script>
+<script src="app/vid/scripts/controller/change-management.controller.js"></script>
+
<script src="app/vid/scripts/directives/extensionsDirective.js"></script>
<script src="app/vid/scripts/directives/parameterBlockDirective.js"></script>
<script src="app/vid/scripts/directives/popupWindowDirective.js"></script>
@@ -51,6 +60,7 @@
<script src="app/vid/scripts/services/propertyService.js"></script>
<script src="app/vid/scripts/services/utilityService.js"></script>
<script src="app/vid/scripts/services/vnfService.js"></script>
+<script src="app/vid/scripts/services/change-management.service.js"></script>
<%@ page import="org.openecomp.vid.mso.*"%>
<%@ page import="org.openecomp.portalsdk.core.util.SystemProperties"%>
diff --git a/vid-app-common/src/test/resources/WEB-INF/jsp/welcome.jsp b/vid-app-common/src/test/resources/WEB-INF/jsp/welcome.jsp
index dcd996892..1396819c7 100644
--- a/vid-app-common/src/test/resources/WEB-INF/jsp/welcome.jsp
+++ b/vid-app-common/src/test/resources/WEB-INF/jsp/welcome.jsp
@@ -1,4 +1,5 @@
+<script src="app/vid/external/multiselect/angular-bootstrap-multiselect.min.js"></script>
<div>
<h1 class="heading1">AT&T Domain 2.0 Network</h1>
<br>
@@ -19,8 +20,8 @@
VID was originally developed for the October 2016 release by an integrated IT and Labs team, under the
direction of Steve Smokowski and Vivian Pressley.
<br><br>
- <h1 class="heading1"><a href="mailto:DL-VIDDeliveryTeam@att.com" target="_top">Contact Us</a></h1>
- <a href="mailto:DL-VIDDeliveryTeam@att.com" target="_top">Please click here to contact us.</a>
+ <h1 class="heading1"><a href="mailto:VID-Tier4@ist.att.com" target="_top">Contact Us</a></h1>
+ <a href="mailto:VID-Tier4@ist.att.com" target="_top">Please click here to contact us.</a>
diff --git a/vid-app-common/src/test/resources/mso.properties b/vid-app-common/src/test/resources/mso.properties
new file mode 100644
index 000000000..8f2bb01a9
--- /dev/null
+++ b/vid-app-common/src/test/resources/mso.properties
@@ -0,0 +1,16 @@
+mso.server.url=http://mtanjv9moah01-eth0.aic.cip.att.com:8080/ecomp/mso/infra
+mso.polling.interval.msecs=2000
+mso.max.polls=3
+mso.user.name=infraportal
+mso.password.x=OBF:1ghz1kfx1j1w1m7w1i271e8q1eas1hzj1m4i1iyy1kch1gdz
+mso.restapi.svc.instance=/serviceInstances/v3
+mso.restapi.vnf.instance=/serviceInstances/v3/<service_instance_id>/vnfs
+mso.restapi.network.instance=/serviceInstances/v3/<service_instance_id>/networks
+mso.restapi.vf.module.instance=/serviceInstances/v3/<service_instance_id>/vnfs/<vnf_instance_id>/vfModules
+mso.restapi.volume.group.instance=/serviceInstances/v3/<service_instance_id>/vnfs/<vnf_instance_id>/volumeGroups
+mso.restapi.get.orc.req=/orchestrationRequests/v3
+mso.restapi.get.orc.reqs=/orchestrationRequests/v3?
+mso.restapi.get.man.tasks=/tasks/v1
+mso.dme2.client.timeout=30000
+mso.dme2.client.read.timeout=120000
+mso.dme2.server.url=http://mso-api-handler-anap-v1.mso.ecomp.att.com/services/ecomp/mso?version=1607&envContext=TEST&routeOffer=st_mtsnj \ No newline at end of file
diff --git a/vid-app-common/src/test/resources/msoRequest.json b/vid-app-common/src/test/resources/msoRequest.json
new file mode 100644
index 000000000..c9397f809
--- /dev/null
+++ b/vid-app-common/src/test/resources/msoRequest.json
@@ -0,0 +1,25 @@
+{
+ "requestDetails": {
+ "requestInfo": {
+ "instanceName": "KLKLKL",
+ "source": "VID",
+ "suppressRollback": false,
+ "requestorId": "1"
+ },
+ "modelInfo": {
+ "modelType": "service",
+ "modelInvariantId": "709d1be4-9a3f-4a29-8c4d-a20465e808a3",
+ "modelVersionId": "1de57bcf-365a-4ba7-8a51-7377b7144586",
+ "modelName": "1707vidnf",
+ "modelVersion": "2.0"
+ },
+ "requestParameters": {
+ "userParams": [],
+ "subscriptionServiceType": "HNGATEWAY",
+ "aLaCarte": true
+ },
+ "subscriberInfo": {
+ "globalSubscriberId": "21014aa2-9e71128cae7-jl319x"
+ }
+ }
+} \ No newline at end of file