use of uk.org.siri.siri_2.LineRefStructure in project onebusaway-application-modules by camsys.
the class ServiceAlertsHelperV2 method handleAffects.
/*
public Date serviceAlertTimeToDate(long time) {
if (time == 0)
return null;
return new Date(time);
}
@SuppressWarnings("unused")
private void handlReasons(PtSituationElementStructure ptSituation,
ServiceAlertBean serviceAlert) {
throw new RuntimeException("handleReasons not implemented");
}
*/
private void handleAffects(ServiceAlertBean serviceAlert, PtSituationElementStructure ptSituation) {
if (serviceAlert.getAllAffects() == null)
return;
boolean hasOperators = false;
AffectsScopeStructure affectsStructure = new AffectsScopeStructure();
VehicleJourneys vehicleJourneys = new VehicleJourneys();
for (SituationAffectsBean affects : serviceAlert.getAllAffects()) {
String agencyId = affects.getAgencyId();
if (agencyId != null) {
Operators operators = new Operators();
if (StringUtils.equals(agencyId, "__ALL_OPERATORS__")) {
operators.setAllOperators("");
} else {
AffectedOperatorStructure affectedOperator = new AffectedOperatorStructure();
affectedOperator.getOperatorName().add(createDefaultedTextStructure(agencyId));
operators.getAffectedOperator().add(affectedOperator);
}
affectsStructure.setOperators(operators);
hasOperators = true;
}
// LineRef
String routeId = affects.getRouteId();
String directionId = affects.getDirectionId();
if (!StringUtils.isBlank(routeId)) {
AffectedVehicleJourneyStructure affectedVehicleJourneyStructure = new AffectedVehicleJourneyStructure();
LineRefStructure lineRefStructure = new LineRefStructure();
lineRefStructure.setValue(routeId);
affectedVehicleJourneyStructure.setLineRef(lineRefStructure);
if (!StringUtils.isBlank(directionId)) {
DirectionRefStructure directionRefStructure = new DirectionRefStructure();
directionRefStructure.setValue(directionId);
affectedVehicleJourneyStructure.setDirectionRef(directionRefStructure);
}
vehicleJourneys.getAffectedVehicleJourney().add(affectedVehicleJourneyStructure);
}
}
if (vehicleJourneys.getAffectedVehicleJourney().size() > 0) {
affectsStructure.setVehicleJourneys(vehicleJourneys);
}
if ((vehicleJourneys.getAffectedVehicleJourney().size() > 0) || hasOperators) {
ptSituation.setAffects(affectsStructure);
}
}
use of uk.org.siri.siri_2.LineRefStructure in project onebusaway-application-modules by camsys.
the class SiriSupportV2 method fillMonitoredVehicleJourney.
/**
* NOTE: The tripDetails bean here may not be for the trip the vehicle is
* currently on in the case of A-D for stop!
* @param filters
*/
public static void fillMonitoredVehicleJourney(MonitoredVehicleJourneyStructure monitoredVehicleJourney, TripBean framedJourneyTripBean, TripStatusBean currentVehicleTripStatus, StopBean monitoredCallStopBean, OnwardCallsMode onwardCallsMode, PresentationService presentationService, TransitDataService transitDataService, int maximumOnwardCalls, List<TimepointPredictionRecord> stopLevelPredictions, boolean hasRealtimeData, DetailLevel detailLevel, long responseTimestamp, Map<Filters, String> filters) {
BlockInstanceBean blockInstance = transitDataService.getBlockInstance(currentVehicleTripStatus.getActiveTrip().getBlockId(), currentVehicleTripStatus.getServiceDate());
List<BlockTripBean> blockTrips = blockInstance.getBlockConfiguration().getTrips();
if (monitoredCallStopBean == null) {
monitoredCallStopBean = currentVehicleTripStatus.getNextStop();
}
/**
*******************************************
*/
// Route ID
LineRefStructure lineRef = new LineRefStructure();
lineRef.setValue(framedJourneyTripBean.getRoute().getId());
DirectionRefStructure directionRef = new DirectionRefStructure();
directionRef.setValue(framedJourneyTripBean.getDirectionId());
// Route Short Name
NaturalLanguageStringStructure routeShortName = new NaturalLanguageStringStructure();
String shortName = framedJourneyTripBean.getRoute().getShortName();
if (!isBlank(currentVehicleTripStatus.getActiveTrip().getRouteShortName())) {
// look for an override like an express desginator
shortName = currentVehicleTripStatus.getActiveTrip().getRouteShortName();
}
if (shortName == null) {
shortName = framedJourneyTripBean.getRoute().getId().split("_")[1];
}
routeShortName.setValue(shortName);
// Agency Id
OperatorRefStructure operatorRef = new OperatorRefStructure();
operatorRef.setValue(AgencySupportLibrary.getAgencyForId(framedJourneyTripBean.getRoute().getId()));
// Framed Journey
FramedVehicleJourneyRefStructure framedJourney = new FramedVehicleJourneyRefStructure();
DataFrameRefStructure dataFrame = new DataFrameRefStructure();
dataFrame.setValue(String.format("%1$tY-%1$tm-%1$td", currentVehicleTripStatus.getServiceDate()));
framedJourney.setDataFrameRef(dataFrame);
framedJourney.setDatedVehicleJourneyRef(framedJourneyTripBean.getId());
// Shape Id
JourneyPatternRefStructure journeyPattern = new JourneyPatternRefStructure();
journeyPattern.setValue(framedJourneyTripBean.getShapeId());
// Destination
NaturalLanguageStringStructure headsign = new NaturalLanguageStringStructure();
headsign.setValue(framedJourneyTripBean.getTripHeadsign());
// Vehicle Id
VehicleRefStructure vehicleRef = new VehicleRefStructure();
if (currentVehicleTripStatus.getVehicleId() == null) {
String tripId = framedJourneyTripBean.getId();
String blockId = framedJourneyTripBean.getBlockId();
String directionId = framedJourneyTripBean.getDirectionId();
String vehicleIdHash = Integer.toString((tripId + blockId + directionId).hashCode());
String agencyName = tripId.split("_")[0];
String vehicleId = agencyName + "_" + vehicleIdHash;
vehicleRef.setValue(vehicleId);
} else {
vehicleRef.setValue(currentVehicleTripStatus.getVehicleId());
}
// Set Origin and Destination stops from Block trips.
StopBean lastStop = new StopBean();
JourneyPlaceRefStructure origin = new JourneyPlaceRefStructure();
for (int i = 0; i < blockTrips.size(); i++) {
BlockTripBean blockTrip = blockTrips.get(i);
if (blockTrip.getTrip().getId().equals(framedJourneyTripBean.getId())) {
List<BlockStopTimeBean> stops = blockTrip.getBlockStopTimes();
origin.setValue(stops.get(0).getStopTime().getStop().getId());
lastStop = stops.get(stops.size() - 1).getStopTime().getStop();
break;
}
}
// location
// if vehicle is detected to be on detour, use actual lat/lon, not
// snapped location.
LocationStructure location = new LocationStructure();
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(6);
if (presentationService.isOnDetour(currentVehicleTripStatus)) {
location.setLatitude(new BigDecimal(df.format(currentVehicleTripStatus.getLastKnownLocation().getLat())));
location.setLongitude(new BigDecimal(df.format(currentVehicleTripStatus.getLastKnownLocation().getLon())));
} else {
location.setLatitude(new BigDecimal(df.format(currentVehicleTripStatus.getLocation().getLat())));
location.setLongitude(new BigDecimal(df.format(currentVehicleTripStatus.getLocation().getLon())));
}
// progress status
List<String> progressStatuses = new ArrayList<String>();
if (presentationService.isInLayover(currentVehicleTripStatus)) {
progressStatuses.add("layover");
}
// "prevTrip" really means not on the framedvehiclejourney trip
if (!framedJourneyTripBean.getId().equals(currentVehicleTripStatus.getActiveTrip().getId())) {
progressStatuses.add("prevTrip");
}
if (!progressStatuses.isEmpty()) {
NaturalLanguageStringStructure progressStatus = new NaturalLanguageStringStructure();
progressStatus.setValue(StringUtils.join(progressStatuses, ","));
monitoredVehicleJourney.getProgressStatus().add(progressStatus);
}
// scheduled depature time
if (presentationService.isBlockLevelInference(currentVehicleTripStatus) && (presentationService.isInLayover(currentVehicleTripStatus) || !framedJourneyTripBean.getId().equals(currentVehicleTripStatus.getActiveTrip().getId()))) {
BlockStopTimeBean originDepartureStopTime = null;
for (int t = 0; t < blockTrips.size(); t++) {
BlockTripBean thisTrip = blockTrips.get(t);
BlockTripBean nextTrip = null;
if (t + 1 < blockTrips.size()) {
nextTrip = blockTrips.get(t + 1);
}
if (thisTrip.getTrip().getId().equals(currentVehicleTripStatus.getActiveTrip().getId())) {
// just started new trip
if (currentVehicleTripStatus.getDistanceAlongTrip() < (0.5 * currentVehicleTripStatus.getTotalDistanceAlongTrip())) {
originDepartureStopTime = thisTrip.getBlockStopTimes().get(0);
// at end of previous trip
} else {
if (nextTrip != null) {
originDepartureStopTime = nextTrip.getBlockStopTimes().get(0);
}
}
break;
}
}
if (originDepartureStopTime != null) {
long departureTime = currentVehicleTripStatus.getServiceDate() + (originDepartureStopTime.getStopTime().getDepartureTime() * 1000);
monitoredVehicleJourney.setOriginAimedDepartureTime(DateUtil.toXmlGregorianCalendar(departureTime));
}
}
Map<String, TimepointPredictionRecord> stopIdToPredictionRecordMap = new HashMap<String, TimepointPredictionRecord>();
// (build map of stop IDs to TPRs)
if (stopLevelPredictions != null) {
for (TimepointPredictionRecord tpr : stopLevelPredictions) {
stopIdToPredictionRecordMap.put(AgencyAndId.convertToString(tpr.getTimepointId()), tpr);
}
}
// monitored call
if (!presentationService.isOnDetour(currentVehicleTripStatus))
fillMonitoredCall(monitoredVehicleJourney, blockInstance, currentVehicleTripStatus, monitoredCallStopBean, presentationService, transitDataService, stopIdToPredictionRecordMap, hasRealtimeData, detailLevel, responseTimestamp);
// detail level - minimal
if (detailLevel.equals(DetailLevel.MINIMUM) || detailLevel.equals(DetailLevel.BASIC) || detailLevel.equals(DetailLevel.NORMAL) || detailLevel.equals(DetailLevel.CALLS)) {
monitoredVehicleJourney.getPublishedLineName().add(routeShortName);
monitoredVehicleJourney.getDestinationName().add(headsign);
monitoredVehicleJourney.setMonitored(currentVehicleTripStatus.isPredicted());
monitoredVehicleJourney.getVehicleMode().add(toVehicleMode(currentVehicleTripStatus.getVehicleType()));
monitoredVehicleJourney.setVehicleRef(vehicleRef);
monitoredVehicleJourney.setBearing((float) currentVehicleTripStatus.getOrientation());
monitoredVehicleJourney.setVehicleLocation(location);
}
// detail level - basic
if (detailLevel.equals(DetailLevel.BASIC) || detailLevel.equals(DetailLevel.NORMAL) || detailLevel.equals(DetailLevel.CALLS)) {
monitoredVehicleJourney.setFramedVehicleJourneyRef(framedJourney);
monitoredVehicleJourney.setDirectionRef(directionRef);
// since LineRef is fully qualified with operatorref, moving OperatorRef to normal detail
// monitoredVehicleJourney.setOperatorRef(operatorRef);
DestinationRefStructure dest = new DestinationRefStructure();
dest.setValue(lastStop.getId());
monitoredVehicleJourney.setDestinationRef(dest);
monitoredVehicleJourney.setLineRef(lineRef);
monitoredVehicleJourney.setProgressRate(getProgressRateForPhaseAndStatus(currentVehicleTripStatus.getStatus(), currentVehicleTripStatus.getPhase()));
}
// detail level - normal
if (detailLevel.equals(DetailLevel.NORMAL) || detailLevel.equals(DetailLevel.CALLS)) {
monitoredVehicleJourney.setOperatorRef(operatorRef);
// block ref
if (presentationService.isBlockLevelInference(currentVehicleTripStatus)) {
BlockRefStructure blockRef = new BlockRefStructure();
blockRef.setValue(framedJourneyTripBean.getBlockId());
monitoredVehicleJourney.setBlockRef(blockRef);
}
monitoredVehicleJourney.setOriginRef(origin);
monitoredVehicleJourney.setJourneyPatternRef(journeyPattern);
}
// onward calls
if (detailLevel.equals(DetailLevel.CALLS)) {
if (!presentationService.isOnDetour(currentVehicleTripStatus))
fillOnwardCalls(monitoredVehicleJourney, blockInstance, framedJourneyTripBean, currentVehicleTripStatus, onwardCallsMode, presentationService, transitDataService, stopIdToPredictionRecordMap, maximumOnwardCalls, responseTimestamp);
}
// situations
fillSituations(monitoredVehicleJourney, currentVehicleTripStatus);
return;
}
use of uk.org.siri.siri_2.LineRefStructure in project onebusaway-application-modules by camsys.
the class RealtimeServiceTest method testStopPointsByBounds.
@Test
public void testStopPointsByBounds() throws Exception {
// MOCKS
// Coordinate Bounds
CoordinateBounds bounds = new CoordinateBounds(Double.parseDouble("47.612813"), Double.parseDouble("-122.339662"), Double.parseDouble("47.608813"), Double.parseDouble("-122.337662"));
// Stops For Bounds
StopsBean stopsBean = new StopsBean();
stopsBean.setStops(stops);
when(transitDataService.getRouteForId("1_100194")).thenReturn(routeBean);
when(transitDataService.getStops(any(SearchQueryBean.class))).thenReturn(stopsBean);
when(transitDataService.getStopsForRoute("1_100194")).thenReturn(stopsForRouteBean);
when(transitDataService.stopHasUpcomingScheduledService(anyString(), anyLong(), anyString(), anyString(), anyString())).thenReturn(true);
// EXPECTED
LineDirectionStructure lds = new LineDirectionStructure();
DirectionRefStructure drs = new DirectionRefStructure();
LineRefStructure lrs = new LineRefStructure();
lds.setDirectionRef(drs);
lds.setLineRef(lrs);
drs.setValue("0");
lrs.setValue("1_100194");
LocationStructure ls = new LocationStructure();
BigDecimal lat = new BigDecimal(47.610813);
BigDecimal lon = new BigDecimal(-122.338662);
ls.setLatitude(lat.setScale(6, BigDecimal.ROUND_HALF_DOWN));
ls.setLongitude(lon.setScale(6, BigDecimal.ROUND_HALF_DOWN));
NaturalLanguageStringStructure stopName = new NaturalLanguageStringStructure();
stopName.setValue("3rd Ave & Pine St");
List<NaturalLanguageStringStructure> stopNames = new ArrayList<NaturalLanguageStringStructure>();
stopNames.add(stopName);
StopPointRefStructure stopPointRef = new StopPointRefStructure();
stopPointRef.setValue("1_430");
Boolean monitored = true;
AnnotatedStopPointStructure mockStopPoint = new AnnotatedStopPointStructure();
mockStopPoint.setLines(new AnnotatedStopPointStructure.Lines());
mockStopPoint.getLines().getLineRefOrLineDirection().add(lds);
mockStopPoint.setLocation(ls);
mockStopPoint.getStopName().add(stopName);
mockStopPoint.setStopPointRef(stopPointRef);
mockStopPoint.setMonitored(monitored);
// REALTIME ARGUMENTS
// Agency Ids
List<String> agencyIds = new ArrayList<String>();
String agencyId = "1";
agencyIds.add(agencyId);
// Route Ids
List<AgencyAndId> routeIds = new ArrayList<AgencyAndId>();
AgencyAndId routeId = AgencyAndIdLibrary.convertFromString("1_100194");
routeIds.add(routeId);
// Detail Level
DetailLevel detailLevel = DetailLevel.NORMAL;
// Time
long time = System.currentTimeMillis();
// Filters
Map<Filters, String> filters = new HashMap<Filters, String>();
Map<Boolean, List<AnnotatedStopPointStructure>> actualResult = realtimeService.getAnnotatedStopPointStructures(bounds, agencyIds, routeIds, detailLevel, time, filters);
AnnotatedStopPointStructure actualStopPoint = actualResult.get(true).get(0);
assertTrue(isEqual(mockStopPoint, actualStopPoint));
}
use of uk.org.siri.siri_2.LineRefStructure in project onebusaway-application-modules by camsys.
the class RealtimeServiceTest method testStopPointsByRoute.
@Test
public void testStopPointsByRoute() throws Exception {
when(transitDataService.getRouteForId("1_100194")).thenReturn(routeBean);
when(transitDataService.getStopsForRoute("1_100194")).thenReturn(stopsForRouteBean);
when(transitDataService.stopHasUpcomingScheduledService(anyString(), anyLong(), anyString(), anyString(), anyString())).thenReturn(true);
LineDirectionStructure lds = new LineDirectionStructure();
DirectionRefStructure drs = new DirectionRefStructure();
LineRefStructure lrs = new LineRefStructure();
lds.setDirectionRef(drs);
lds.setLineRef(lrs);
drs.setValue("0");
lrs.setValue("1_100194");
LocationStructure ls = new LocationStructure();
BigDecimal lat = new BigDecimal(47.610813);
BigDecimal lon = new BigDecimal(-122.338662);
ls.setLatitude(lat.setScale(6, BigDecimal.ROUND_HALF_DOWN));
ls.setLongitude(lon.setScale(6, BigDecimal.ROUND_HALF_DOWN));
NaturalLanguageStringStructure stopName = new NaturalLanguageStringStructure();
stopName.setValue("3rd Ave & Pine St");
List<NaturalLanguageStringStructure> stopNames = new ArrayList<NaturalLanguageStringStructure>();
stopNames.add(stopName);
StopPointRefStructure stopPointRef = new StopPointRefStructure();
stopPointRef.setValue("1_430");
Boolean monitored = true;
AnnotatedStopPointStructure mockStopPoint = new AnnotatedStopPointStructure();
mockStopPoint.setLines(new AnnotatedStopPointStructure.Lines());
mockStopPoint.getLines().getLineRefOrLineDirection().add(lds);
mockStopPoint.setLocation(ls);
mockStopPoint.getStopName().add(stopName);
mockStopPoint.setStopPointRef(stopPointRef);
mockStopPoint.setMonitored(monitored);
// REALTIME ARGUMENTS
// Agency Ids
List<String> agencyIds = new ArrayList<String>();
String agencyId = "1";
agencyIds.add(agencyId);
// Route Ids
List<AgencyAndId> routeIds = new ArrayList<AgencyAndId>();
AgencyAndId routeId = AgencyAndIdLibrary.convertFromString("1_100194");
routeIds.add(routeId);
// Detail Level
DetailLevel detailLevel = DetailLevel.NORMAL;
// Time
long time = System.currentTimeMillis();
// Filters
Map<Filters, String> filters = new HashMap<Filters, String>();
Map<Boolean, List<AnnotatedStopPointStructure>> actualResult = realtimeService.getAnnotatedStopPointStructures(agencyIds, routeIds, detailLevel, time, filters);
AnnotatedStopPointStructure actualStopPoint = actualResult.get(true).get(0);
assertTrue(isEqual(mockStopPoint, actualStopPoint));
}
use of uk.org.siri.siri_2.LineRefStructure in project onebusaway-application-modules by camsys.
the class StopPointsActionTest method initialize.
@Before
public void initialize() throws Exception {
// Agencies
Map<String, List<CoordinateBounds>> agencies = new HashMap<String, List<CoordinateBounds>>();
agencies.put("1", new ArrayList<CoordinateBounds>(Arrays.asList(new CoordinateBounds(47.410813, -122.038662, 47.810813, -122.638662))));
agencies.put("3", new ArrayList<CoordinateBounds>(Arrays.asList(new CoordinateBounds(0.0, 0.0, 0.0, 0.0))));
agencies.put("40", new ArrayList<CoordinateBounds>(Arrays.asList(new CoordinateBounds(47.510813, -122.138662, 47.710813, -122.538662))));
// Route Bean
Builder routeBuilder = RouteBean.builder();
routeBuilder.setAgency(new AgencyBean());
routeBuilder.setId("1_100194");
routeBean = routeBuilder.create();
// Route Bean List
routes = new ArrayList<RouteBean>(1);
routes.add(routeBean);
// Stop Bean
stopBean = new StopBean();
stopBean.setId("1_430");
stopBean.setName("3rd Ave & Pine St");
stopBean.setLon(-122.338662);
stopBean.setLat(47.610813);
stopBean.setRoutes(routes);
// Stop Bean List
stops = new ArrayList<StopBean>(1);
stops.add(stopBean);
// Stop Group
stopIds = new ArrayList<String>(1);
stopIds.add(stopBean.getId());
stopGroupName = new NameBean("destination", "Destination");
stopGroup = new StopGroupBean();
stopGroup.setId("0");
stopGroup.setStopIds(stopIds);
stopGroup.setName(stopGroupName);
// Stop Group List
stopGroups = new ArrayList<StopGroupBean>(1);
stopGroups.add(stopGroup);
// Stop Grouping
stopGrouping = new StopGroupingBean();
stopGrouping.setStopGroups(stopGroups);
// Stop Grouping List
List<StopGroupingBean> stopGroupings = new ArrayList<StopGroupingBean>(1);
stopGroupings.add(stopGrouping);
// Stops For Route
stopsForRouteBean = new StopsForRouteBean();
stopsForRouteBean.setRoute(routeBean);
stopsForRouteBean.setStopGroupings(stopGroupings);
stopsForRouteBean.setStops(stops);
// LineDirectionStructure
LineDirectionStructure lds = new LineDirectionStructure();
DirectionRefStructure drs = new DirectionRefStructure();
LineRefStructure lrs = new LineRefStructure();
lds.setDirectionRef(drs);
lds.setLineRef(lrs);
drs.setValue("0");
lrs.setValue("1_100194");
// Location Structure
LocationStructure ls = new LocationStructure();
BigDecimal lat = new BigDecimal(47.610813);
BigDecimal lon = new BigDecimal(-122.338662);
ls.setLongitude(lon.setScale(6, BigDecimal.ROUND_HALF_DOWN));
ls.setLatitude(lat.setScale(6, BigDecimal.ROUND_HALF_DOWN));
// StopNames
NaturalLanguageStringStructure stopName = new NaturalLanguageStringStructure();
stopName.setValue("3rd Ave & Pine St");
List<NaturalLanguageStringStructure> stopNames = new ArrayList<NaturalLanguageStringStructure>();
stopNames.add(stopName);
// StopPointRef
StopPointRefStructure stopPointRef = new StopPointRefStructure();
stopPointRef.setValue("1_430");
// Monitored
Boolean monitored = true;
// AnnotatedStopPointStructure
AnnotatedStopPointStructure mockStopPoint = new AnnotatedStopPointStructure();
mockStopPoint.setLines(new AnnotatedStopPointStructure.Lines());
mockStopPoint.getLines().getLineRefOrLineDirection().add(lds);
mockStopPoint.setLocation(ls);
mockStopPoint.getStopName().add(stopName);
mockStopPoint.setStopPointRef(stopPointRef);
mockStopPoint.setMonitored(monitored);
List<AnnotatedStopPointStructure> mockStopPoints = new ArrayList<AnnotatedStopPointStructure>(1);
mockStopPoints.add(mockStopPoint);
Map<Boolean, List<AnnotatedStopPointStructure>> annotatedStopPointMap = new HashMap<Boolean, List<AnnotatedStopPointStructure>>();
annotatedStopPointMap.put(true, mockStopPoints);
when(realtimeService.getAnnotatedStopPointStructures(anyListOf(String.class), anyListOf(AgencyAndId.class), any(DetailLevel.class), anyLong(), anyMapOf(Filters.class, String.class))).thenReturn(annotatedStopPointMap);
// XML Serializer
SiriXmlSerializerV2 serializer = new SiriXmlSerializerV2();
when(realtimeService.getSiriXmlSerializer()).thenReturn(serializer);
// Print Writer
PrintWriter nothingPrintWriter = new PrintWriter(new OutputStream() {
@Override
public void write(int b) throws IOException {
// Do nothing
}
});
when(servletResponse.getWriter()).thenReturn(nothingPrintWriter);
when(transitDataService.getRouteForId("1_430")).thenReturn(routeBean);
when(transitDataService.getStopsForRoute("1_430")).thenReturn(stopsForRouteBean);
when(transitDataService.stopHasUpcomingScheduledService(anyString(), anyLong(), anyString(), anyString(), anyString())).thenReturn(true);
when(transitDataService.getAgencyIdsWithCoverageArea()).thenReturn(agencies);
}
Aggregations